vuex-orm / plugin-graphql

Vuex ORM persistence plugin to sync the store against a GraphQL API.
https://vuex-orm.github.io/plugin-graphql/
MIT License
227 stars 52 forks source link

Cannot read property 'primaryKey' of undefined #77

Closed marfrelen closed 5 years ago

marfrelen commented 5 years ago

Hello everyone.

I'm trying to persist data from a frontend to a backend server using vuex orm graphql plugin.

async createNewCar() {
        await Car.create( {data: this.car} )
        let car = Car.query().whereFk("n").first()
        await car.$persist()
      }

this.car is a computed property and looks like this:

      car() {
        return {
          id: "n",
          name: this.name,
          garage_id: this.garage.id,
        }
      }

After calling the await car.$persits() command, I get the following error message:

app.js:764 TypeError: Cannot read property 'primaryKey' of undefined
    at Query.push../node_modules/@vuex-orm/core/dist/vuex-orm.esm.js.Query.whereFk (vendors.app.js:3624)
    at BelongsToMany.push../node_modules/@vuex-orm/core/dist/vuex-orm.esm.js.BelongsToMany.addEagerConstraintForPivot (vendors.app.js:1079)
    at BelongsToMany.push../node_modules/@vuex-orm/core/dist/vuex-orm.esm.js.BelongsToMany.load (vendors.app.js:1066)
    at Function.push../node_modules/@vuex-orm/core/dist/vuex-orm.esm.js.Loader.eagerLoadRelations (vendors.app.js:3051)
    at Query.push../node_modules/@vuex-orm/core/dist/vuex-orm.esm.js.Query.collect (vendors.app.js:3895)
    at Query.push../node_modules/@vuex-orm/core/dist/vuex-orm.esm.js.Query.get (vendors.app.js:3564)
    at BelongsTo.push../node_modules/@vuex-orm/core/dist/vuex-orm.esm.js.BelongsTo.load (vendors.app.js:755)
    at Function.push../node_modules/@vuex-orm/core/dist/vuex-orm.esm.js.Loader.eagerLoadRelations (vendors.app.js:3051)
    at Query.push../node_modules/@vuex-orm/core/dist/vuex-orm.esm.js.Query.collect (vendors.app.js:3895)
    at Query.push../node_modules/@vuex-orm/core/dist/vuex-orm.esm.js.Query.get (vendors.app.js:3564)

Hope anyone can help me.

Thank you ;)

phortx commented 5 years ago

How does your model definition of car looks like? And what computed prop is that? I'm not sure I fully understood your code :D

marfrelen commented 5 years ago

Good morning ;)

I'm sorry and I understand you. I'm not allowed to talk about the project I'm working on, so I thought up a stupid case to describe it :D

So maybe let me explain the environment:

We have a laravel based backend, using lighthouse to support the graphql api on backend site. The frontend is a nuxt application using vuex orm in combination with the graphql plugin.

So in our case the frontend will be used to create a cars which should be stpred in the database in the backend.

When I create a car the $persist() function crashes.

The car model:

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

/**
 * @export
 * @class District
 * @extends {Model}
 */

export default class Car extends Model {
  /*eslint-disable */
  static entity = 'fields';

  static primaryKey = 'id';
  /* eslint-enable */

  // List of all fields (schema) of the post model. `this.attr` is used
  // for the generic field type. The argument is the default value.
  static fields() {
    return {
      id: this.attr(null),
      name: this.string(''),
      garage_id: this.attr(null),
      garage: this.belongsTo(Garage, 'garage_id'),
    }
  }
}

I hope that will help you to give me some support.

As I said, I'm very sorry for my shitty example use case :D

marfrelen commented 5 years ago

Okay I solved the Problem.

The Garage type has a many to many relation to the user type and I forgot to register the pivot model. That was the reason for the undefined property.

Never the less I have another question.

Is there a possibility to create a new model (e.g. a car one) via $persist() and avoid to create the related models?

async createNewCar() {
        await Car.create( {data: this.car} )
        let car = Car.query().whereFk("n").first()
        await car.$persist()
      }

The command above (await car.$persist()) creates the following query:

mutation CreateCar($car: CarInput!) {
  createCar(car: $car) {
    id
    name
    garage {
      id
      name
      area
      street
      region
      municipality
      owner {
        id
        lastname
        firstname
        email
      }
    }
  }
}

And I just want to do this:

mutation CreateCar($car: CarInput!) {
  createCar(car: $car) {
    id
    name
    garage_id 
}
phortx commented 5 years ago

avoid to create the related models?

It doesn't create the other models, it just generates a query to fetch those related stuff after the server has created them. On the server you can decide wether you want to create them or not.

However currently there is no possibility to disable eagerLoading (which is what happens here) for single queries. Maybe in the future.

phortx commented 5 years ago

Moved to https://github.com/vuex-orm/plugin-graphql/issues/95