0

I am new to Vue.js - it would be so great to receive help . thanks.

I have the API working fine and the Select works fine - SO the code below is working -- EXCEPT it has duplicate values showing.Null values have been removed -- but duplicates are still there.

I would like to solve how to filter the list for the select dropdown to have unique values.

Here is the Model (cut down)

class USERaffylinks(models.Model):
    owner_link_useraffyid = models.ForeignKey(USERaffiliates, on_delete=models.CASCADE) #link(s) for each partner stores the  id from USERaffiliates
    owner_link_short = models.CharField(max_length=27, null=True, default=None, blank=True) 
    owner_link_long = models.URLField(max_length=100, null=True, default=None, blank=True) 
    linked_from_typedesc  = models.CharField(max_length=12, null=True, default=None, blank=True)

Here is the API code with COMPUTED CODE

export default {
    name: 'addlink',
    data() {
        return {
            links: [],
            linkitem: 0,
        }
    },
    props: ['value'],

    created: function(){
        this.getLinks()
    },

computed: {
        options() {
            const unique_ids = [ ...new Set(  // make list of unique ids
                    this.links
                    .filter(link => Boolean(link.linked_from_typedesc)) // removes falsey like null
                    .map(link => link.linked_from_typedesc)) // returns linked_from_typedesc only
                    ];
            return this.links.filter(link => unique_ids.includes(link.linked_from_typedesc));
            },
        },

    methods: {
        
        getLinks() {
            axios.get("http://127.0.0.1:8000/api/affypartnerlinks/")
                 .then(function (response) {
                this.links = response.data;
                }.bind(this));
          },

And here is the HTML

<div v-if="!addtype">
                                        <select id="linktypelist" v-model="linkitem">
                                            <option disabled value="0">Select or Add</option>
                                            <option v-for='link in options' v-bind:value="link.linked_from_typedesc" :key="link.id" >{{ link.linked_from_typedesc }}</option>
                                        </select>
                                    </div>

IMAGE OF DROP DOWN with duplicates

IMAGE OF DROP DOWN with duplicate

So this all works fine except the duplicate showing up - which I want to remove

I am using the final value selected in link.linked_from_typedesc to store in my table.

Thanks kindly David

David
  • 9
  • 1
  • 4
  • is `link.id` unique and not null ? – Ashwin Bande Jan 18 '21 at 11:56
  • yes @ashwinbande it is – David Jan 18 '21 at 11:59
  • I have added a image to show the drop down - with duplicates and blanks ... I am using the selected TEXT to store in DB and not the record id. – David Jan 18 '21 at 12:59
  • I added in the v-bind:value="link.linked_from_typedesc" seeing this was missed on my original code -- – David Jan 18 '21 at 14:45
  • I made some tweeks to the Options function code to use the `code`linked_from_typedesc`code` field instead of the id field -- and it DOES remove NULL but NOT duplicates ... the duplicates are still there – David Jan 19 '21 at 02:37
  • am pretty sure in list returned by objects contains objects with unique `linked_from_typedesc` value; So how duplicates are possible; reproduce a minimal example on codepen to understand your problem. – Ashwin Bande Jan 19 '21 at 03:54

2 Answers2

0

to filter by link.id so it is not duplicate and null or undefined try following:

make a computed value named options

computed: {
  options() {
    const unique_ids = [ ...new Set(  // make list of unique ids
               this.links
               .filter(link => Boolean(link.id)) // removes falsey like null
               .map(link => link.id)) // returns id only
             ];
    return this.links.filter(link => unique_ids.includes(link.id));

  },
}

use this computed property options in your select options like this

<select id="linktypelist" v-model="linkitem">
    <option disabled value="0">Select or Add</option>
    <option v-for='link in options' :key="link.id" >{{ link.linked_from_typedesc }}</option>
</select>
Ashwin Bande
  • 2,693
  • 2
  • 10
  • 22
  • Thank you so much for this @aswinbande - but This does not affect the list of values - it does not filter the list. I have added the image above to the drop down after using your code -- this is the same result I have right now --- I think you may be thinking I need to store the id -- but I am going to use the TEXT from the dropdown to store in DB. – David Jan 18 '21 at 12:37
  • I added in the v-bind:value="link.linked_from_typedesc" seeing this was missed on my original code -- – – David Jan 18 '21 at 14:45
  • I have changed id for linked_from_typedesc in your options function -- and this now works to get rid of the NULL -- but does NOT remove duplicates -- I have updated my original Q to reflect the new problem now - hope that's not confusing! – David Jan 19 '21 at 03:19
0

From https://stackoverflow.com/a/12551750/5877209

computed: {
     options() {
       const unique_ids = this.links.filter(function(key){
          if (!this[key.id]) { this[key.id] = 1;return key.id;}},
                {}
                );
          return unique_ids;

  },
}
anju
  • 589
  • 12
  • 25
  • I solved this issue in the end by changing the VIEW and adding .distinct('linked_from_typedesc') and switched DB to postgres – David Jan 27 '21 at 08:09
  • okay, so you modified it from the query itself? – anju Jan 27 '21 at 09:44
  • Yes @anju - I could not get the JS code to filter duplicates for some reason -- so switched my server to postgress so I could filter there - thanks for your kind help – David Jan 28 '21 at 10:53