Friday, May 28, 2021

Bidirectional relations and circular dependency issue

 Want to fetch all users from a given company.

We can do that with below graphql query:

graphql query:
{
  company(id"1"){
   id
   name
   description
users{
id
firstname
age
}
  }
  }

But, Above query doesn't work as we linked users to company but not the vice-versa.

to set this route in graph, to fetch all users in a company.

check in json data first.: http://localhost:3000/companies/1/users

if the data is available, update in CompanyType in schema.

const CompanyType = new GraphQLObjectType({
  name: "Company",
  fields: {
    id: { type: GraphQLString },
    name: { type: GraphQLString },
    description: { type: GraphQLString },
    users: {
      type: new GraphQLList(UserType),
      resolve(parentValue,args){
        return axios.get(`http://localhost:3000/companies/${parentValue.id}/users`)
          .then(res=>res.data);
      }
    }
  },
});

But,we might get dependency error if UserType is defined after CompanyType in the code.

But UserType is also depenedent on CompanyType, so we will get similar error if we change the order.

So, to fix this circular dependency, keep then in a fields in arrow function as below, so it won't be in static code and will fetch on dynamic execution.

const CompanyType = new GraphQLObjectType({
  name: "Company",
  fields:()=>( {
    id: { typeGraphQLString },
    name: { typeGraphQLString },
    description: { typeGraphQLString },
    users: {
      typenew GraphQLList(UserType),
      resolve(parentValue,args){
        return axios.get(`http://localhost:3000/companies/${parentValue.id}/users`)
          .then(res=>res.data);
      }
    }
  })
});

const UserType = new GraphQLObjectType({
  name: "User",
  fields:()=>( {
    id: { typeGraphQLString },
    firstName: { typeGraphQLString },
    age: { typeGraphQLInt },
    company: {
      typeCompanyType,
      resolve(parentValueargs) {
        //used when field names with database and here are different
        console.log(parentValueargs);
        return axios
          .get(`http://localhost:3000/companies/${parentValue.companyId}`)
          .then((res) => res.data);
      },
    },
  })
});

Then, we can call as many nested quesries as deep we want.

//graphql query
{
  company(id"1"){
   id
   name
   description
   users{
    id
    firstname
    age
    company{
      name
      users{
       name
       company{
         name
      }
      }
    }
  }
  }
  }

No comments:

Post a Comment