6

I am trying to fetch List of sobjects and show them in data table. I want to add a hyperlink to record name. I am using @wired property to dynamically get records depending on the search term.

my test.js

@track data = [];
@track error;
@track columns = [{
        label: 'Some name', fieldName: 'linkName', type: 'url', sortable: true, 
        typeAttributes: {label: { fieldName: 'Name' },value:{fieldName: 'linkName'}, target: '_blank'}}];


@wire(apexSearch,{searchTerm: "$searchTerm1"})

wiredTenders({error, data}) {
   if (data) {
       this.data = Object.assign({}, data);
       var a  = JSON.parse(JSON.stringify(this.data));

       for (var i = 0; i < data.length; i++) {
           console.log('1.5)'+(a[i]));
            if(a[i].linkName) a[i].linkName = '/'+a[i].Id;
        }
        console.log('2)'+data);
    } else if (error) {
        this.error = error;
    }
 }

The linkName never gets filled i.e I cannot see a hyperlink and also no data shows up in data table. I checked that the var a contains the list of objects. enter image description here I used this.data = Object.assign({}, data); due to the explanation in this post: Uncaught TypeError: 'set' on proxy: trap returned falsish for property Name

Any suggestions would be helpful. Thanks!

3
  • its unclear what problem you are facing - what do you mean by never gets filled ? is data even returning something? or is it undefined? thanks – glls Apr 8 '19 at 21:55
  • Hi, I don't see any data in table and also when I debug it never finds a[i].linkName.. – SFlearner Apr 8 '19 at 22:08
  • looks like you are trying to create a navigation link, which is not recomended if you are trying to redirect within a salesforce record, is there any reason why you are not using a NavigationMixin function? – glls Apr 9 '19 at 0:04
17

here is a solution that works perfectly. I display a list of opportunity and add a hyperlink on the column name of the data table. To do that, you have to create a wrapper class in you apex controller like this:

public with sharing class GetAllOpportunities {
   @AuraEnabled(cacheable=true)
    public static List<DataTableWrapper> getAllOpps() {
        List<Opportunity> listOpp = [SELECT Id, Name ,StageName, CloseDate 
                                     FROM Opportunity Order By Name asc];

        List<DataTableWrapper> response = new List<DataTableWrapper>();
        for(Opportunity opp : listOpp){
            DataTableWrapper obj = new DataTableWrapper();
            obj.oppId = opp.Id;
            obj.name = opp.Name;
            obj.nameUrl = '/'+opp.Id;
            obj.stageName = opp.StageName;
            obj.closeDate = opp.CloseDate;
            response.add(obj);
        }

        return response;
    }

    private class DataTableWrapper {
        @AuraEnabled
        public Id oppId {get;set;}
        @AuraEnabled
        public String name {get;set;}
        @AuraEnabled
        public String nameUrl {get;set;}
        @AuraEnabled
        public String stageName {get;set;}
        @AuraEnabled
        public Date closeDate {get;set;}
    }


}

note the nameUrl attribute, I'll use it in the js file.

here is the html file:

<template>
    <lightning-card  title="Opportinity List">
        <lightning-datatable data={opportunities} columns={columns} key-field="Id"></lightning-datatable>        
    </lightning-card> 
</template>

And Finally, the js file:

import { LightningElement ,wire,track} from 'lwc';
import getAllOpps from '@salesforce/apex/GetAllOpportunities.getAllOpps';

export default class OpportunityList extends LightningElement {
    @track columns = [
        {
            label: 'Opportunity name',
            fieldName: 'nameUrl',
            type: 'url',
            typeAttributes: {label: { fieldName: 'name' }, 
            target: '_blank'},
            sortable: true
        },
        {
            label: 'Stage Name',
            fieldName: 'stageName',
            type: 'text',
            sortable: true
        },
        {
            label: 'Close date',
            fieldName: 'closeDate',
            type: 'date',
            sortable: true
        }

    ];

    @track error;
    @track opportunities = [];


    @wire(getAllOpps)
    wiredOpps({error,data}) {
        if (data) {
            this.opportunities = data;
            this.error = undefined;
        } else if (error) {
            this.error = error;
            this.opportunities = undefined;
        }
    }
}

==========================================================================

Update

=========================================================================

This code below does the same thing without creating any wrapper class. We can only use JS.

import { LightningElement ,wire,track} from 'lwc';
import getAllOpps from '@salesforce/apex/GetAllOpportunities.getAllOpps';

export default class OpportunityList extends LightningElement {
    @track columns = [
        {
            label: 'Opportunity name',
            fieldName: 'nameUrl',
            type: 'url',
            typeAttributes: {label: { fieldName: 'Name' }, 
            target: '_blank'},
            sortable: true
        },
        {
            label: 'Stage Name',
            fieldName: 'StageName',
            type: 'text',
            sortable: true
        },
        {
            label: 'Close date',
            fieldName: 'CloseDate',
            type: 'date',
            sortable: true
        }

    ];

    @track error;
    @track opportunities = [];


    @wire(getAllOpps)
    wiredOpps(result) {
        const { data, error } = result;
        if(data) {
            let nameUrl;
            this.opportunities = data.map(row => { 
                nameUrl = `/${row.Id}`;
                return {...row , nameUrl} 
            })
            this.error = null;
        }
        if(error) {
            this.error = error;
            this.opportunities = [];
        }
    }
}

Apex class

public with sharing class GetAllOpportunities {
   @AuraEnabled(cacheable=true)
    public static List<Opportunity> getAllOpps() {
        return [SELECT Id, Name ,StageName, CloseDate FROM Opportunity Order By Name asc];
    }

}
4
  • One small thing, your JS code has the field names for Stage Name and Close Date mis spelled. You have stageName and closeDate, they need to be StageName and CloseDate (capatilized first letter) to match the field names. – ScottH7a9 Jan 14 '20 at 15:49
  • Yeah @ ScottH7a9 you're right, updated – dibocor Jan 15 '20 at 16:33
  • What an awesome answer +1 – CommonCoreTawan Jun 16 '20 at 19:02
  • This answer is great and works too but how can we do this using lightning navigation instead that way the experience is same as how it is for standard links. this one redirects to a URL and then refresh the page to land me to the record even if the record is open in an adjacent object tab. – Nishant Singh Panwar Jul 2 '20 at 19:16
1

You may want to review this earlier question/answer:

Lightning Web Component - Navigation - Show Link in a List / Table to Open Record

I was having similar issue / wanting to do the same thing. I ended up creating a small LWC Component (navigationLink) that will create a link using a passed record Id.

3
  • can you share your code for navigation link lwc – Nishant Singh Panwar Jul 2 '20 at 18:58
  • I wat something generic to pass an Id and label and put that for any lookup type fields in my datatable – Nishant Singh Panwar Jul 2 '20 at 18:58
  • @NishantSinghPanwar The code is in a response at the question linked above. "Lightning Web Component - Navigation - Show Link in a List / Table to Open Record" – Paul N Jul 3 '20 at 19:37
0

I have added posted code in my blog where we dont need to have wrapper class https://www.salesforcepoint.com/2020/06/how-to-add-hyper-link-for-name-column.html

1
  • Can you include the code in your post? Links tend to die over time so if your blog shuts down this answer will not longer be helpful to users. – nbrown Jun 23 '20 at 15:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.