13

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, 2019 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, 2019 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, 2019 at 0:04

2 Answers 2

34

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];
    }
    
}
5
  • 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, 2020 at 15:49
  • Yeah @ ScottH7a9 you're right, updated
    – dibocor
    Jan 15, 2020 at 16:33
  • What an awesome answer +1 Jun 16, 2020 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. Jul 2, 2020 at 19:16
  • Great answer. Thanks for providing both the APEX Wrapper method, and the JS method. Jan 20, 2023 at 16:57
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 Jul 2, 2020 at 18:58
  • I wat something generic to pass an Id and label and put that for any lookup type fields in my datatable Jul 2, 2020 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, 2020 at 19:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .