mesqueeb / vuex-easy-firestore

Easy coupling of firestore and a vuex module. 2-way sync with 0 boilerplate!
https://mesqueeb.github.io/vuex-easy-firestore
MIT License
234 stars 28 forks source link

[planned feature] placeholder document before server retrieval #122

Open mesqueeb opened 5 years ago

mesqueeb commented 5 years ago

Placeholder document before server retrieval

When working a lot with VueJS and components, you will notice that Vue components often give an error when they rely on data that doesn't exist.

In the example below we will get an error if the passedProp is undefined. It will say something like:

cannot read showMe of undefined

<template><div v-if="passedProp.showMe">🧐</div></template>
<script>
export default {
  props: ['passedProp']
}
</script>

This is very annoying if your Vue components rely on data from Firestore. They will give a lot of errors just before the data is retrieved from the server via openDBChannel or fetchAndAdd.

Manual workaround 1: v-if in template

You can manually prevent your templates from rendering before the data arrives by adding a lot of v-if statements on the top level div. However, when working with a lot of components and a lot of data, this quickly becomes cumbersome. There is a better option in my opinion:

Manual workaround 2: a placeholder object

Module in 'doc' mode: πŸ‘

You can just write your default values in the state of your Vuex module. These will be overwritten with the server data when you open openDBChannel or fetchAndAdd. And all components that expect some data will be able to use the default data to render before the data from the server arrives.

Module in 'collection' mode: πŸ‘Ž

There is one problem when doing this in 'collection' mode: By adding a "placeholder object" inside your module state (inside the data prop), that placeholder object will still be there after the server data is retrieved!

Temporary placeholder document by Vuex Easy Firestore

You can define 'default values' for your documents. These are really good for preventing Vue reactivity bugs, when certain documents from the server don't have a value that is expected in a component.

In Vuex Easy Firestore, these 'default values' are also used to temporarily add a placeholder document to your collection. Below we will show an example of how your vuex-easy-firestore module will look before and after server retrieval of the documents:

const myModule = {
  firestorePath: 'myDocs',
  firestoreRefType: 'collection',
  moduleName: 'myModule',
  statePropName: 'data',
  sync: {
    defaultValues: {
      showMe: true,
    },
  }
}

// myModule before openDBChannel or fetchAndAdd
state: {
  data: {
    '*': {showMe: true, id: '*'} // placeholder document added automatically
  }
}

// myModule after openDBChannel or fetchAndAdd
state: {
  data: {
    // placeholder document REMOVED AGAIN automatically
    // ... (documents from server)
  }
}

You do not have to do anything extra! As long as there are defaultValues you will have a lot less trouble when your components are rendered before the data is retrieved from the server! πŸŽ‰


After about two years of open source, I finally got accepted for Github Sponsors!

πŸ’œ github.com/sponsors/mesqueeb πŸ’œ

A little about me:

If anyone was helped with vuex-easy-firestore, I'd greatly appreciate any support!

BTW, donations get's paid DOUBLE by GitHub! (they're alchemists... 🦾)

Going forward πŸ‘¨πŸΌβ€πŸ’»

louisameline commented 4 years ago

This issue will go away with nested modules as you know :D They'll be instantiated with their empty state.

louisameline commented 4 years ago

I think for now you have provided a working solution, so I will close this issue.

mesqueeb commented 4 years ago

@louisameline I'm not sure this will go away with nested modules. I want to preferably keep this open until just before launching v2 to carefully decide how to best implement this.

Eg. 1 module per document allows its state to have the default values, BUT, we need to think about new docs registered, where they get these default values from and how to be able to provide placeholder docs before reading data from the database.

Think opening the facebook app and it shows a bunch of posts with big grey lines until actual server data replaces the grey lines with text. That's what I'm imagining. (probably for a plugin though :P)

louisameline commented 4 years ago

I might not understand. Nested modules will be an instance of a class module or something like that, which can be used by the dev independantly from the library if he needs to check what the structure is. Just like i currently sometimes import the state.js file of a module in my own code when I need to. Also I think UI placeholders are commonly not using any data, they rather use grey lines and squares that simulate text and images layout.