Displayed items of DropDownList don't update after adding items to source

Hey folks,

I am currently using the DropDownList in a vue.js project. The array which is passed as the :dataSource prop is initially filled from a vuex store by th"beforeMount()" hook. Everything works well so far.

Now when I update the array (by vuex store mutation), the new entries are not populated into the items of the DropDownList component, eventhough to my understanding the "one-way-binding"
concept of vue.js should do exactly this. At first I thought that it might be my array not being a reactive property, but I checked it via inspection and adding it into a watch and it actually
updates just fine once the vuex store gets mutated.

I saw that there was a similar issue with the same component in the (bare) javascript forum and the solution was to rebind the dataSource, but i really dont think that this should be an
expected behaviour when using a framework like vue or react as it is a central feature of these frameworks.

4 Replies

PO Prince Oliver Syncfusion Team October 3, 2018 03:21 PM UTC

Hi Boris, 
 
Thank you for contacting Syncfusion support. 
 
We have prepared a sample based on your shared scenario. We have assigned dataSource through beforeMount event through Vuex store and updated the dataSource dynamically through button click. Please refer to the below given code 
 
export default new Vuex.Store({ 
  state: { 
    items: [ 
      { Name: 'Andrew Fuller', Designation: 'Team Lead', Country: 'England' }, 
      { Name: 'Anne Dodsworth', Designation: 'Developer', Country: 'USA' }, 
      { Name: 'Janet Leverling', Designation: 'HR', Country: 'USA' }, 
      { Name: 'Laura Callahan', Designation: 'Product Manager', Country: 'USA' }, 
      { Name: 'Margaret Peacock', Designation: 'Developer', Country: 'USA' }, 
      { Name: 'Michael Suyama', Designation: 'Team Lead', Country: 'USA' }, 
      { Name: 'Nancy Davolio', Designation: 'Product Manager', Country: 'USA' }, 
      { Name: 'Robert King', Designation: 'Developer ', Country: 'England' }, 
      { Name: 'Steven Buchanan', Designation: 'CEO', Country: 'England' } 
    ] 
  }, 
 
  mutations: { 
    MUTATE_ITEMS: (state, items) => { 
      state.items = items; 
    } 
  }, 
 
  actions: { 
    loadItems: (context, items) => { 
      context.commit("MUTATE_ITEMS", items); 
    } 
  }, 
  getters: { 
    items(state) { 
      return state.items; 
    } 
  } 
}); 
 
 
<template> 
  <h1> 
      <ejs-dropdownlist :dataSource='items' :fields='fields' ref="ddlInstance"></ejs-dropdownlist> 
  </h1> 
    
</template> 
 
<script> 
import Vue from "vue"; 
import { mapGetters } from "vuex"; 
import { DropDownListPlugin } from "@syncfusion/ej2-vue-dropdowns"; 
Vue.use(DropDownListPlugin); 
export default { 
  name: "ItemList", 
  data: function () { 
    return { 
       
        fields: { value: 'Designation' ,text: 'Name' } 
    }  
  }, 
     beforeMount: function(e) { 
       this.items= this.$store.state.items; 
    }, 
  computed: { 
    ...mapGetters(["items"]), 
    items: { 
      set:function(){ 
       return this.$store.state.items; 
      }, 
      get:function(){ 
return this.$store.state.items; 
      }      
    } 
  } 
}; 
</script> 
 
 
If the issue persists, kindly modify the above sample to reproduce the issue in our end so that we can proceed further. 
 
Regards, 
Prince 



BO Boris October 24, 2018 09:15 PM UTC

Hello,

please excuse my late answer on this, but I have been busy on different projects lately.

I have taken a look at your example and found it working just fine. I adjusted your example to match the issue i described in my post. Essentially I just add a mutation that adds new object to the items array. While the added items are displayed when displayed as <li v-for="item in items"> elements, they are not displayed in the dropdown list of the component _eventhough_ they arrive properly in that component as the "vue devtools" indicate.

Adjusted store.js:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
state: {
items: [
{ Name: 'Andrew Fuller', Designation: 'Team Lead', Country: 'England' },
{ Name: 'Anne Dodsworth', Designation: 'Developer', Country: 'USA' },
{ Name: 'Janet Leverling', Designation: 'HR', Country: 'USA' },
{ Name: 'Laura Callahan', Designation: 'Product Manager', Country: 'USA' },
{ Name: 'Margaret Peacock', Designation: 'Developer', Country: 'USA' },
{ Name: 'Michael Suyama', Designation: 'Team Lead', Country: 'USA' },
{ Name: 'Nancy Davolio', Designation: 'Product Manager', Country: 'USA' },
{ Name: 'Robert King', Designation: 'Developer ', Country: 'England' },
{ Name: 'Steven Buchanan', Designation: 'CEO', Country: 'England' }
]
},
mutations: {
MUTATE_ITEMS: (state, items) => {
state.items = items;
},
ADD_ITEM: (state, item) => {
state.items.push(item);
}
},
actions: {
loadItems: (context, items) => {
context.commit("MUTATE_ITEMS", items);
},
addItem: (context, item) => {
context.commit("ADD_ITEM", item);
}
},
getters: {
items(state) {
return state.items;
}
}
});

Adjusted App.vue:

<template>
<h1>
<ejs-dropdownlist :dataSource='items' :fields='fields' ref="ddlInstance"></ejs-dropdownlist>
<Button v-on:click="addObjects">Add</Button>
</h1>
</template>

<script>
import Vue from "vue";
import { mapGetters } from "vuex";
import { DropDownListPlugin } from "@syncfusion/ej2-vue-dropdowns";
Vue.use(DropDownListPlugin);
export default {
name: "ItemList",
data: function () {
return {
fields: { value: 'Designation' ,text: 'Name' }
}
},
beforeMount: function(e) {
this.items= this.$store.state.items;
},
computed: {
...mapGetters(["items"]),
items: {
set:function(){
return this.$store.state.items;
},
get:function(){
return this.$store.state.items;
}
}
},
methods: {
addObjects() {
var newobj = { Name: 'Boris Lange', Designation: 'Developer', Country: 'Germany' }
this.$store.dispatch('addItem', newobj)
}
}
};
</script>

<style>
@import "../node_modules/@syncfusion/ej2-vue-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
</style>



Screenshot of dropdown component state is attached to this post.




BO Boris October 24, 2018 09:21 PM UTC

Attaching the screenshot didnt work as .png so attached it as a zip now..

Attachment: ejsdropdownstate_ccb3aeb8.zip


PO Prince Oliver Syncfusion Team October 25, 2018 11:37 AM UTC

Hi Boris, 

Thank you for your update. 

We were able to reproduce the issue using the shared code snippet. On validating the issue, we found that this issue occurs because you have directly pushed an item into existing array using push. Currently we have not provided support for push and pop detection in dropdown components. So, we suggest you push the items to existing array and assign this final array for state.items as shown below 

mutations: {  
  MUTATE_ITEMS: (state, items) => {  
    state.items = items;  
  }, 
  ADD_ITEM: (state, item) => { 
    state.items.push(item) 
    state.items=[...state.items]; 
  } 
},  

We have attached modified sample for your reference, please find the sample in the following link: 

Regards, 
Prince 


Loader.
Up arrow icon