Vue-material: [mdAutocomplete] Error in nextTick: "Error: You should use a `fetch` function prop"

Created on 25 Aug 2017  ·  23Comments  ·  Source: vuematerial/vue-material

Hello,

i want to use md autocomplete, with list prop and filteredList but i have an error

Error in nextTick: "Error: You should use a fetch function prop"

my code below :
<md-autocomplete :min-chars="3" v-model="searchAgenciesQuery" :list="agencies" :filter-list="filteredAgencies" ">

agencies is the result of my promise

Services.getAgencies({size: 1000, page: 0}).then(resp => {
        this.agencies = resp
      })

filteredAgencies is my filter method :

filteredAgencies () {
        let query = this.searchAgenciesQuery
        if (query) {
          return this.agencies.filter(agency => {
            let filterByName = agency.name ? agency.name.toLowerCase().includes(query.toLowCase()) : ''
            let filterById = agency.id !== null ? agency.id.includes(query) : ''
            return filterByName || filterById
          })
        }
      }

I don't understand the difference between list prop and fetch prop. I don't use fetch cuz i have to store locally my agencies, so my promise is not for the fetch that it should return but it implement on the created, so i dont want to use fetch way

 created () {
      Services.getAgencies({size: 1000, page: 0}).then(resp => {
        this.agencies = resp
      })
    },

Thanks a lot for your help

All 23 comments

i tried with fetch prop and i have

this.fetch(...).then is not a function

my code :

<md-autocomplete :min-chars="3" v-model="searchAgenciesQuery" :fetch="filteredAgencies"></md-autocomplete>

methods: {
      filteredAgencies (param) {
        let query = param.q
        let filtered = this.agencies.filter(agency => {
          let filterByName = agency.name ? agency.name.toLowerCase().includes(query.toLowerCase()) : ''
          let filterByRegion = agency.address.region ? agency.address.region.toLowerCase().includes(query.toLowerCase()) : ''
          let filterById = agency.id !== null ? agency.id.includes(query) : ''
          return filterByName || filterById || filterByRegion
        })
        return query.length >= 1 ? filtered : this.agencies
      }
    }

I wrote an example for you.

filter-list: Yous should pass a function.

{
  methods:{
    filterList: (list, inputString) => {
      // do some thing
      return result
    }
  }
}

fetch: You should return a promise in your fetch method or declare it as an async function.

{
  methods:{
    fetch: async ({q}) => {
      let inputString = q
      let result = await getResult(inputString)
      return result
    }
  }
}

Use list and filter props if you don't need to do an async method (like ajax) to get the result,
or use fetch props if you have to.

It's more likely better to use list and filter props than fetch in your case that you only fetch the list once on component created.

Hello,

Thank you for your helping !
I understand now difference between differents props list and fetch but i cannot use it but I'm sorry i can't make it works, i have this error

You should use a filterList function prop with the list prop

methods: {
      filteredAgencies: (agencies = this.agencies, query = this.searchAgenciesQuery) => {
        return agencies.filter(agency => {
          let filterByName = agency.name ? agency.name.toLowerCase().includes(query.toLowerCase()) : ''
          let filterByRegion = agency.address.region ? agency.address.region.toLowerCase().includes(query.toLowerCase()) : ''
          let filterById = agency.id !== null ? agency.id.includes(query) : ''
          return filterByName || filterById || filterByRegion
        })
      }
    }

I pass anonymous method to filteredAgencies and my html is the same as before:
<md-autocomplete :min-chars="3" v-model="searchAgenciesQuery" :list="agencies" :filter-list="filteredAgencies"></md-autocomplete>

What error did you got?

Could you please reproduce it in codepen?

i simplify some code (i mocked calls instead of calling service get etc.. ) but the logic is the same
thank you !
my error :

[Vue warn]: Error in nextTick: 'Error: You should use a filterList function prop with the list prop'

<p data-height="265" data-theme-id="0" data-slug-hash="wqYJew" data-default-tab="result" data-user="Alex_Mugen" data-embed-version="2" data-pen-title="Vue Material Issue #1002" class="codepen">See the Pen <a href="https://codepen.io/Alex_Mugen/pen/wqYJew/">Vue Material Issue #1002</a> by Alex (<a href="https://codepen.io/Alex_Mugen">@Alex_Mugen</a>) on <a href="https://codepen.io">CodePen</a>.</p> <script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

oups , i changed version of dependencies now it's work on codepen , i set the last version of vuejs and vue material as my package json in my project :

"vue": "^2.3.3",
    "vue-material": "^0.7.1"

But in my project it still not works it shows error

You should use a filterList function prop with the list prop

and when i try to write some text in my input

Cannot read property 'focus' of undefined

Cannot read property 'value' of undefined

is it possible it is a version problem ? because i try with my first version of my code as above and it works.. But it looks strange because in my package json i tell to get the last version started from *

"vue": "^2.3.3",
    "vue-material": "^0.7.1"
[Vue warn]: Avoid using non-primitive value as key, use string/number value instead.

~Because the list should be a list of distinct strings.~

e.g.

{
  data () {
    return {
      list: ['str1', 'str2', 'str3']
    }
  }
}

You put objects in list array.

Thus, the key of the menu is the agency objects. That cause this warning.

~It's better to computed a distinct string array list from the original list to pass as :list~

~Autocomplete component is a helper for a string, not a selecter for an object.~

updated: #issuecomment-325378263

thank you for your explanation for

[Vue warn]: Avoid using non-primitive value as key, use string/number value instead.

I tried differents solutions but i cannot find the right , i have again

vue.esm.js?65d7:566 Error: You should use a filterList function prop with the list prop

while on the copen it works

I cannot help you if you don't reproduce it.

I misunderstood about the warning:

[Vue warn]: Avoid using non-primitive value as key, use string/number value instead.

I check the code b802afd mdAutocomplete line 26

That list should be an object list so it's seem like the warning always happen. I think it's an issue.

You could decide what property key to show or select by the :print-attribute, which default is name.

ok thank you for the precision :1st_place_medal:

i'm trying to understand my bug with

Error: You should use a filterList function prop with the list prop

I cannot understand the mistake..
https://codepen.io/Alex_Mugen/pen/wqYJew?editors=1011 i copy paste the same from my webpack project to my codepen ( expect method get that calling service but even if i mockup agencies with array static it doesn't work ) and it works on codepen only

In my project ,

i have a template :
<md-autocomplete :min-chars="3" v-model="searchAgenciesQuery" :list="agencies" :filter-list="filteredAgencies"></md-autocomplete>

i have a created that get agencies :

Services.getAgencies({size: 1000, page: 0}).then(resp => {
        this.agencies = resp
      })

I have a methods that contains filteredAgencies :

filteredAgencies () {
        console.log('filteredAgencies')
        return this.agencies.filter(agency => {
          let filterByName = agency.name ? agency.name.toLowerCase().includes(this.searchAgenciesQuery.toLowerCase()) : ''
          let filterByRegion = agency.address.region ? agency.address.region.toLowerCase().includes(this.searchAgenciesQuery.toLowerCase()) : ''
          let filterById = agency.id !== null ? agency.id.includes(this.searchAgenciesQuery) : ''
          return this.searchAgenciesQuery.length > 1 ? filterByName || filterById || filterByRegion : this.agencies
        })
      },

and that 's all ...
:sos:

Did you upgrade the modules to latest version?

i think is already the latest version because in my package json i have
"vue": "^2.3.3", "vue-material": "^0.7.1"

It means that it take the latest right ?

Execute this command in your project directory to check modules installed

npm ls --depth=0

Thank you !
It looks like ok for latest version

[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

:thinking:

i compared two code again and it's exaclty the same, i set my agencies as a local array like in code pen because it s the only difference but it doesn't work :imp:

Sorry i missed something ,

i tested to set a local array like this :

Services.getAgencies({size: 1000, page: 0}).then(resp => {
        this.agencies = [{name:'toto', region: 'test', id: '123'},
                     {name:'tata', region: 'aze', id: '456'},
                     {name:'titi', region: 'taiwan', id: '789'}]
      })

instead of set agencies without promise

this.agencies = [{name:'toto', region: 'test', id: '123'},
                     {name:'tata', region: 'aze', id: '456'},
                     {name:'titi', region: 'taiwan', id: '789'}]

now i have the error we talked before

[Vue warn]: Avoid using non-primitive value as key, use string/number value instead.

It's not a fatal error. I think you could ignore it temporarily.

I have no idea whether this change with the key of the menu item is a good idea or not:

<md-menu-item v-if="items.length"
  v-for="item in items"
  :key="item[printAttribute]"
  @keyup.enter="hit(item)"
  @click="hit(item)">
  {{ item[printAttribute] }}
</md-menu-item>

ok , i will use md-autocomplete if it'ss not a fatal error !

i want to say you thank you a lot :1st_place_medal:

Kept getting the error

You should use a filterList function prop with the list prop

Tinkered around and got it to work like this

<md-input-container>
   <label class="specialSelect">AutoComplete</label>
   <md-autocomplete name="autoComplete" id="autoComplete" :filterList="someFunction" :min-chars="0" :list="[{name:''}]"  v-model="myModel"></md-autocomplete>
   <md-button v-if="myModel" @click="myModel = '' " class="md-icon-button">
      <md-icon>clear</md-icon>
   </md-button>
</md-input-container>

.
.
.

methods:{
    someFunction() {
      // TODO actual filtering
      return this.myList;
    },
    getFunctionThatIsCalledOnCreate(){
          this.$http.get(url, {}).then((response) => {
        var result = response.data;
        if (this.myList != result.myListFromServer) {
          var outputList = [];
          for (var k in result.myListFromServer) {
           // Pretty sure there are better and easier ways of doing this (converting string array to object array with a prop)
            var line = result.myListFromServer[k];
            outputList.push({ name: line });            
          }
          if (outputList != null && outputList != [])
            this.myList = outputList;
        }
      })
   }
}

Using name since its default but can be changed in 'print-attribute' prop

Closing this issue as our focus is on the new 1.0.0 version.

In case anyone is using the 0.8.1 version and gets this error. It happens when the initial state of the list you're pointing to is empty. Simply initialize the list with fake data. Something like:

list= [{name: 'loading', id: -1}]

Was this page helpful?
0 / 5 - 0 ratings

Related issues

korylprince picture korylprince  ·  3Comments

philipfeldmann picture philipfeldmann  ·  3Comments

xinzhanguo picture xinzhanguo  ·  3Comments

diverted247 picture diverted247  ·  3Comments

bryanspearman picture bryanspearman  ·  3Comments