Pinia + fetch

Hello everyone. I am very new in Vue and I want to write a simple like CRM for my job purposes.
So, I have an API where json objects are fetched from and I need this data to use in all components. For this reason I installed Pinia to my project, created store and used fetch API to fetch data to it in my App.vue. This is my store config:

export const useStore = defineStore('data', {
state: () => ({
    particulars: [],
    seafarers: [],
    ports: []
})
})

And this is how I fetch data into it:

const store = useStore()

fetch(this.$baseUrl + '/api/vessel-data?populate=%2A')
  .then((res) => res.json())
  .then(data => {
    store.$patch({
      particulars: data.data.attributes,
    })
  })
  .catch(error => console.log(error.msg))

fetch(this.$baseUrl + '/api/seafarers')
  .then((res) => res.json())
  .then(data => {
    store.$patch({
      seafarers: data.data,
    })
  })
  .catch(error => console.log(error.msg))

fetch(this.$baseUrl + '/api/ports')
  .then((res) => res.json())
  .then(data => {
    store.$patch({
      ports: data.data
    })
  })
  .catch(error => console.log(error.msg))
  }

Now the problem is when in component I try to get data from store for example store.particulars it is ok, but when I try to get something more nested like store.particulars.nested1.nested2.nested3.field it throws me an error that it is undefined, but console.log(store.particulars) shows that it has that field.
What’s wrong in my code? How can I reach my purpose the proper way?

UPD: When I open the Pinia section in Vue Dev Tools it also shows me that all data is good and NOT ‘undefined’ anywhere.

Hi @maxonlinux
This could be a latency problem. It could be a problem of waiting. may be intruduce await and variables.
const someVar = store.particulars
const nestedObjects = someVar.nested
and also use await or promise along side.

Yes, I assume so. But for now I have no idea how to make component wait for data to be completely fetched. For example, if I want to render something like {{store.particulars.nested1.nested2.nested3.field}} in the template, it throws an error “undefined” and the app breaks. The first thoughts would be about using v-if, but it also throws me an undefined, unless I specify not the whole part but only before some certain level of nesting, e.g. v-if="tore.particulars.nested1.nested2" and it works good. But I think this is not a solution to experiment every time on which level of object nesting the v-if stops throwing me an error and then renders specified field. Any ideas?

yes @maxonlinux That is a very deep nesting.
Sometime the undefined comes from type related error.
so you might use ‘?’ to make sure it is conditional.
store.particulars?.nested1?.nested2?.nested3?.field

but if it is a fetch await problem.
you can check it like so

new Promise((resolveOuter) => {
  resolveOuter(
    new Promise((resolveInner) => {
      setTimeout(console.log(field), 1000);
    })
  );
});
you can go deeper with the above one. use it chained with the '?" operator

I am appreciated for your help.
And I want to tell you that usage of the ?. solved the problem :joy: I don’t even know how the optional chaining operator regards to that, but it does really work. I believe that timings between checking of each data in chain are just enough to finish the data loading.

1 Like