plugin-graphql
plugin-graphql copied to clipboard
Problem to $persist
I dont know why I cant persist and object... I got: fetch, push and destroy works well.
vuex-orm-graphql.es5.js?8eb2:1 Uncaught (in promise) TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at Function.e.transformOutgoingData (vuex-orm-graphql.es5.js?8eb2:1)
at Function.e.addRecordToArgs (vuex-orm-graphql.es5.js?8eb2:1)
at Function.eval (vuex-orm-graphql.es5.js?8eb2:1)
at eval (vuex-orm-graphql.es5.js?8eb2:1)
at Object.eval [as next] (vuex-orm-graphql.es5.js?8eb2:1)
at eval (vuex-orm-graphql.es5.js?8eb2:1)
at new Promise (<anonymous>)
at __awaiter (vuex-orm-graphql.es5.js?8eb2:1)
at Function.t.call (vuex-orm-graphql.es5.js?8eb2:1)
Sector,js
import { Model } from '@vuex-orm/core'
export default class Sector extends Model {
static entity = 'sectors'
static fields () {
return {
id: this.number(null),
name: this.string(''),
}
}
}
store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import VuexORM from '@vuex-orm/core';
import VuexORMGraphQL from '@vuex-orm/plugin-graphql';
import { AuthModule } from './auth-module';
import { HttpModule } from './http-module';
import { SettingsModule } from './settings-module';
import { CustomAdapter } from '@/plugins/graphql-adapter';
import ApolloClient from '@/plugins/apollo-client';
// Create a new instance of Database.
const database = new VuexORM.Database();
// Models
import User from '@/models/User';
import Sector from '@/models/Sector';
import Subsector from '@/models/Subsector';
import Segment from '@/models/Segment';
// Register Models to Database.
database.register(User);
database.register(Sector);
database.register(Subsector);
database.register(Segment);
VuexORM.use(VuexORMGraphQL, {
database,
adapter: new CustomAdapter(),
apolloClient: ApolloClient
});
Vue.use(Vuex);
export default new Vuex.Store({
plugins: [VuexORM.install(database)],
modules: {
auth: AuthModule,
http: HttpModule,
settings: SettingsModule
},
});
Sector.vue
<script>
import Sector from '@/models/Sector';
export default {
data() {
return {
sector: {},
}
},
async mounted() {
await Sector.fetch();
},
computed: {
sectors: () => Sector.all(),
},
methods: {
newf() {
this.sector = {};
},
edit(sector) {
this.sector = sector;
},
async create() {
await Sector.insert({data: this.sector});
const sector = Sector.query().last();
await sector.$persist();
},
async update() {
await this.sector.$push();
},
async destroy(sector) {
await sector.$deleteAndDestroy();
}
}
};
</script>
For Vuex ORM the key of model is attribute "$id" as we can see in:
vuex-orm/query/Query.ts
private deleteById (id: string | number | (number | string)[]): Data.Item {
const item = this.find(id)
if (!item) {
return null
}
return this.deleteByCondition(model => model.$id === item.$id)[0]
}
When the model has increment id, its set to "$id" and "id" attributes the key value, but when the model doesnt have increment id , its set the fictitious key only to "$id" attribute.
Then, the plugin cant get data by "id" attribute on:
plugin-graphql/orm/model.ts
public getRecordWithId(id: number) {
return this.baseModel
.query()
.withAllRecursive()
.where("id", id)
.first();
}
In where should be "$id".
Another problem, its seems possible in Vuex ORM have more then one attribute as model key and plugin graphql is not prepered for this situation, as we can see in:
Vuex ORM/model/Model.ts
async $delete (): Promise<Item<this>> {
const primaryKey = this.$primaryKey()
if (!Array.isArray(primaryKey)) {
return this.$dispatch('delete', this[primaryKey])
}
return this.$dispatch('delete', (model: this): boolean => {
return primaryKey.every(id => model[id] === this[id])
})
}
@vuex-orm/core 0.34 solves the problem of null id, because Uid generate to $id and id attributes. But the plugin still dont work with composite keys
With the latest release, the plugin works with Vuex-ORM 0.36. Feel free to reopen the issue when the problem still exists :)
Thank you very much for the update =]
This is still an issue as it tries to convert a string
id into a number before performing the search query.
https://github.com/vuex-orm/plugin-graphql/blob/50d0bb689bcc8dd7b0db4692ca51f2596621db6c/src/orm/model.ts#L267
I am using string ids in many of my models. Hat to fork the Repo and remove all "toNumber" calls in the code. Hope it will be fixed soon
With generated $id: "tyr13zqj"
I have the same error Uncaught (in promise) TypeError: Cannot convert undefined or null to object
.
Seems that now (vuex-orm/core 0.36.3) it not prefixed with $uid
in models:
id: this.uid(() => tempId()) // tempId returns 'tyr13zqj' value
But in plugin code we have
getRecordWithId(id) {
return this.baseModel
.query()
.withAllRecursive()
.where("id", toPrimaryKey(id))
.first();
}
where toPrimaryKey
is
function toPrimaryKey(input) {
if (input === null)
return 0;
if (typeof input === "string" && (input.startsWith("$uid") || isGuid(input))) {
return input;
}
return parseInt(input.toString(), 10);
}
Why you need that conversion in plugin? Just return string if that is string!