Reputation: 143
In GraphQL (Apollo, Sequelize and SQLite), I am using a field to resolve the model type of a polymorphic association. When caching, a problem in resolving the association appears.
Backend:
class AssignTModel extends Model {
async getAction(options) {
if (!this.actionType) return Promise.resolve(null);
const mixinMethodName = `get${uppercaseFirst(this.actionType)}`;
const action=await this[mixinMethodName](options);
if (action) action.myResolve=this.actionType;
return action;
}
}
AssignTModel.init({
id:{ type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true },
. . .
actionId:{ type: Sequelize.INTEGER},
actionType:{ type: DataTypes.STRING },
}, {sequelize,modelName: 'assignt'});
. . .
AssignTModel.belongsTo(ReminderModel, { foreignKey: 'actionId', constraints: false });
AssignTModel.belongsTo(ServiceModel, { foreignKey: 'actionId', constraints: false });
const AssignT = sequelize.models.assignt;
. . .
const typeDefs = gql`
union Action = Reminder | Service
type AssignT{
id:Int
. . .
action:Action
}
. . .
type Query {
. . .
action(id:Int):[Action],
. . .
const resolvers = {
. . .
Action:{
__resolveType(obj, context, info){
if(obj && obj.myResolve && obj.myResolve === "reminder" ){
return 'Reminder';
}
if(obj && obj.myResolve && obj.myResolve === "service" ){
return 'Service';
}
return null;
},
},
. . .
AssignT: {
. . .
action: async (assignt) => assignt.getAction(),
},
Frontend:
In the React.JS application when I enable Cache on a Query I am getting a problem in resolving the polymorphic association:
FORM_QUERY = gql`query ($id:Int){
nodes:assignT(id:$id){
id
. . .
action {
... on Reminder{
id
label
}
... on Service{
id
label
}
}
}
}`;
Not OK --> <Query query={FORM_QUERY} variables={{id:id}} fetchPolicy="cache-and-network">
OK --> <Query query={FORM_QUERY} variables={{id:id}} fetchPolicy="no-cache">
This problem does not appear on the GraphQL Playground that is why I doubted the Cache.
How can I solve this problem while maintaining Cache?
Upvotes: 1
Views: 211
Reputation: 143
Found and solved. I am posting the answer so it may help someone facing the same problem.
The problem was about not using the IntrospectionFragmentMatcher. In fact, I have seen this warning but I was planning to solve it later on and did not directly make the link to my problem.
the solution is as follows:
import { InMemoryCache, NormalizedCacheObject,IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import {ApolloClient} from "apollo-boost";
const possibleTypes = {
__schema: {
types: [{
kind: 'UNION',
name: 'Action',
possibleTypes: [
{ name: 'Service' },
{ name: 'Reminder' },
]
},
]
},
}
const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData: possibleTypes
})
const cache = new InMemoryCache({
fragmentMatcher
})
const uri= 'http://localhost:4000/';
const link = createHttpLink({ uri, fetch });
const client= new ApolloClient({
cache,
link
});
Upvotes: 1