javascriptvue.jsvuexvuex-orm

Vuex-ORM insert and merge two api calls related to each other


Having problem here to understand the benefits of Vuex-ORM in my special case.

I have a rest API and most of the time i manage to handle my data with a multiple api calls to display the result.

For example: Having a call for fetchUsers() and a call for fetchPosts, posts are made by the users and are related within as a userId prop.

UsersData

const users = [
  {
    id: 1,
    name: 'Leanne Graham',
    username: 'Bret',
    email: 'Sincere@april.biz',
  },
  {
    id: 2,
    name: 'Ervin Howell',
    username: 'Antonette',
    email: 'Shanna@melissa.tv',
  },
  {
    id: 3,
    name: 'Clementine Bauch',
    username: 'Samantha',
    email: 'Nathan@yesenia.net',
  },
  {
    id: 4,

PostData

const posts = [
  {
    userId: 1,
    id: 1,
    title:
      'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
    body:
      'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto',
  },
  {
    userId: 2,
    id: 2,
    title: 'qui est esse',
    body:
      'est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla',
  },
  {
    userId: 3,
    id: 3,
    title: 'ea molestias quasi exercitationem repellat qui ipsa sit aut',
    body:
      'et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut',
  },
  {
    userId: 3,
    id: 4,
    title: 'eum et est occaecati',
    body:
      'ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit',
  },
  {
    userId: 5,
    id: 5,
    title: 'nesciunt quas odio',
    body:
      'repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque',
  },
]

with this as prepare i go to call these two api's async in my store actions.

import Vue from 'vue'
import Vuex from 'vuex'

// import mock api data
import usersData from '@/data/users'
import postsData from '@/data/posts'

// import to VUEX-ORM Database
import User from '@/store/models/User'
import Post from '@/store/models/Post'

import VuexORM from '@vuex-orm/core'

Vue.use(Vuex)

const database = new VuexORM.Database()

database.register(User)
database.register(Post)

export default new Vuex.Store({
  plugins: [VuexORM.install(database)],
  getters: {
    users: () => {
      return User.all()
    },
    posts: () => {
      return Post.all()
    },
  },
  actions: {
    async fetchUsers() {
      const fetchingUsers = await new Promise((resolve, reject) => {
        return setInterval(() => {
          resolve(usersData)
          reject(
            'Issue on fetching, but usually this is not possible in a mock'
          )
        }, 300)
      })
      User.insert({ data: fetchingUsers })
    },
    async fetchPosts() {
      const fetchingPosts = await new Promise((resolve, reject) => {
        return setInterval(() => {
          resolve(postsData)
          reject(
            'Issue on fetching, but usually this is not possible in a mock'
          )
        }, 300)
      })
      Post.insert({ data: fetchingPosts })
    },
    deleteUser(context, userId) {
      User.delete((user) => user.id === userId)
    },
    addUser(context, userData) {
      userData.id = User.all().length + 1
      User.insertOrUpdate({ data: userData })
    },
  },
  modules: {},
})

all i want now is that the Posts should get into there related Users my models are defined like this:

User Model

import { Model } from '@vuex-orm/core'
import Post from './Post'

export default class User extends Model {
  static entity = 'user'
  static fields() {
    return {
      id: this.attr(null),
      name: this.attr(''),
      username: this.attr(''),
      email: this.attr(''),
      posts: this.hasMany(Post, 'userId')
    }
  }
}

Post Model

import { Model } from '@vuex-orm/core'
import User from './User'

export default class Post extends Model {
  static entity = 'post'
  static fields() {
    return {
      id: this.attr(null),
      userId: this.belongsTo(User, 'id'),
      title: this.attr(''),
      body: this.attr(''),
    }
  }
}

big question is, why is my Posts not getting into my Users Object so i can display Users with their belonged posts. my array of posts inside my User is empty. anyone an idea why? empty array


Solution

  • What you're seeing in vue-devtools is expected.

    Relationships are not inserted into the store, they are inserted into their respective "tables" and assigned foreign keys to create a reference to that relationship.

    When you query your entities to include relations i.e. User.query().with('posts').get() you'll notice that posts will be populated. The relationship fields in the store however will always show as empty array's (for many relations) or null (for single relations) since this is simply the schema for the entity.