0

I have a Users model with some fields and reference to "Skills" model.

The models are look like this below

1.Users.js (users model)

 const mongoose = require('mongoose');
 const Schema = mongoose.Schema;

 const UsersSchema = new Scheam({
     name: { type : String },
     email: { type : String },
     address: { type : String },

     Skills: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Skills' }],
 })

 module.exports = mongoose.model('Users', UsersSchema);

2.Skills Model

const mongoose = require('mongoose')
const Schema = mongoose.Schema;

const SkillsSchema = new Schema({
   name : { type: String },
});

module.exports = mongoose.model('Skills', SkillsSchema);

I am creating the new user with dropdown menu of skills selection storing the id's of the skills in users model.

And getting the skills by populating the Users model like this in node js app.

  export function getUser(req, res) {
     console.log('getUser');
     console.log('req.body',req.body);
     Users.findOne({_id: req.body.user_id}).populate('skills').exec(function(err, usr_doc){ 
       if(err) {
          res.json({
             status: 401,
             message: 'something went wrong!',
             err: err,
          });
       } else if (!err && usr_doc != null) {
           res.json({
               status: 200,
               message: 'User details found!',
               data: {_id: usr_doc._id, skills: usr_doc.skills,name: usr_doc.name,token: usr_doc.token},
           })
       }
     })//Users.findOne end
  }

The above code is working fine for normal rest api.

Here I try to create the Same api using GraphQL server of express-graphql in Nodejs.

The code look like this.

3.Schema.js

 const graphql = require('graphql');
 const Users = require('../models/Users');
 const Skills = require('../models/Skills');

 const { 
    GraphQLObjectType,
    GraphQLInt,
    GraphQLFloat,
    GraphQLString, 
    GraphQLSchema,
    GraphQLID,
    GraphQLList,
    GraphQLNonNull,
    GraphQLBoolean,
    GraphQLObject
 } = graphql;

 const UsersType = new GraphQLObjectType ({
       name: 'Users',
       fields: () => ({
            id: {type: GraphQLID},
            name: { type : GraphQLString },
            email: { type : GraphQLString },
            **skills: {
                type: new GraphQLList(SkillsType),
                resolve(parent, args){
                  //Here I need to know how to get the skills name of the users
                }
            }**
       })

   const SkillsType = new GraphQLObjectType({
       name: 'Skills',
       fields: () => ({
          name: { type : GraphQLString },
       })
   })    

At present I didn't use any reference id in skills model, only name. I want to get the skill names of the Users.

If i use the below, I am getting all of the skill names instead of user particular or populated skill names.

   skills : {
     type: new GraphQLList(SkillsType),
        resolve(parent, args){
            return Skills.find({})
        } 

Please provide any suggestions regarding this.

I can give more information if you need.

Venkatesh Somu
  • 4,710
  • 4
  • 23
  • 22
  • have you tried? resolve(parent, args){ //Here I need to know how to get the skills name of the users return await Skills.find({"_id": {$in: parent.skills} }) } – Shivam Pandey Dec 03 '18 at 13:04
  • Hi @Shivam Pandey, I tried your code that works like a charm. Please post it as an answer, I will accept it. Thank you. – Venkatesh Somu Dec 04 '18 at 03:05
  • Sure @Venkatesh Somu – Shivam Pandey Dec 04 '18 at 04:57
  • Hi @Shivam Pandey. I have small doubt regarding the saving of array values like skill ids ["123213","3234434","2231232"] in CreateUser Mutation. Can you please tell me how to define schem type for array values and saving them in resolve function. – Venkatesh Somu Dec 05 '18 at 12:06
  • Basically, you need to add `input` keyword, input UserInput { skills: [String]} – Shivam Pandey Dec 05 '18 at 13:28

1 Answers1

1

To get the skills of a user, instead of Skills.find({}) which returns all the documents present in the skills collection, add a condition there with the parent object.

The parent object, which contains result from the resolver on the parent field here. So skills, a child resolver, can be written as:

 skills: {
     type: new GraphQLList(SkillsType),
     resolve(parent, args) {
         return await Skills.find({"_id": {$in: parent.skills} }) }
 } 
Shivam Pandey
  • 3,756
  • 2
  • 19
  • 26