Search code examples
node.jsgraphqlapollo-server

Graphql is returning "Cannot read property 'id' of undefined", [apollo server, node.js]


I am trying to display one course and to update course topic, using graphql and apollo-server. This is my code:

const { ApolloServer, gql } = require('apollo-server');

var typeDefs=gql`
input CourseInput {
    id: Int
    title: String
    author: String
    description: String
    topic: String
    url: String
}
type Course {
    id: Int
    title: String
    author: String
    description:String
    topic:String
    url: String
}
type Query {
    course(id: Int!): Course
    courses(topic:String!):[Course]
    allcourses:[Course]
    hello: String

}
type Mutation {
    updateCourseTopic(id: Int !, topic: String !): Course
    createCourse(input: CourseInput): [Course]
    deleteCourse(id: Int !): [Course]
}
`;

var coursesData = [
    {
        id: 1,
        title: 'The Complete Node.js Developer Course',
        author: 'Andrew Mead, Rob Percival',
        description: 'Learn Node.js by building real-world applications with Node, Express, MongoDB, Mocha, and more!',
        topic: 'Node.js',
        url: 'https://codingthesmartway.com/courses/nodejs/'
    },
    {
        id: 2,
        title: 'Node.js, Express & MongoDB Dev to Deployment',
        author: 'Brad Traversy',
        description: 'Learn by example building & deploying real-world Node.js applications from absolute scratch',
        topic: 'Node.js',
        url: 'https://codingthesmartway.com/courses/nodejs-express-mongodb/'
    },
    {
        id: 3,
        title: 'JavaScript: Understanding The Weird Parts',
        author: 'Anthony Alicea',
        description: 'An advanced JavaScript course for everyone! Scope, closures, prototypes, this, build your own framework, and more.',
        topic: 'JavaScript',
        url: 'https://codingthesmartway.com/courses/understand-javascript/'
    }
]
var getCourses = function(args){
    console.log("delila2")
    if(args.topic){
        console.log("delila2")
        var topic=args.topic;
        return coursesData.filter(course=>
            course.topic===topic
        );

    }
    else return coursesData
    
}

var resolvers= {
Query:{
  course:getcourse,
  courses:getCourses,
  allcourses:getAllCourses,
  hello: ()=>"Delila"
},
Mutation: {
  updateCourseTopic:updateCourseTopic,
  createCourse:createCourse,
  deleteCourse: deleteCourse,
}
};

function getcourse(args){
    var id=args.id;
    return coursesData.filter(course=>{
        return course.id==id
    })[0]
 

}
function getAllCourses(){
    console.log("all courses")
    return coursesData;
}
function updateCourseTopic (id, topic){
  console.log("id je" ,id)
    coursesData.map(course=>{
        if(course.id===id){
            course.topic=topic;
            return course
        }
    });
    console.log("svi", coursesData);
    return coursesData.filter(course=>course.id===id)[0]
    
}
function createCourse(input){
    var id = 4;
    coursesData = [...coursesData, input.input];
    console.log("input je" ,input.input)
    console.log("coursesdata" ,coursesData)
    //coursesData[id] = input;
    return coursesData;

}
function deleteCourse(args){
    var id=args;
    coursesData.splice(id, 1);
    return coursesData;

}

// The ApolloServer constructor requires two parameters: your schema
// definition and your set of resolvers.
const server = new ApolloServer({ typeDefs, resolvers });

// The `listen` method launches a web server.
server.listen().then(({ url }) => {
  console.log(`🚀  Server ready at ${url}`);
});

On my localhost server http://localhost:4000 using graphql and this code I am trying to fetch data to get one specific course and to update course topic.

Get single course:

query getSingleCourse($courseID: Int !){
  course(id:$courseID){
    title
    author
    description
    url
    topic
  }
}
{
  "courseID": 3
}

Update course topic:

mutation updateCourse($id: Int!, $topic: String !) {
  updateCourseTopic(id:$id, topic:$topic)
  {
    title
    url
    description
    author
    topic
  }
}
{
  "id": 1,
  "topic": "something new"
}

The problem is with getSingleCourse is that

"errors": [ { "message": "Cannot read property 'id' of undefined", "locations": [ { "line": 2, "column": 3 } ], "path": [ "course" ], "extensions": { "code": "INTERNAL_SERVER_ERROR", "exception": { "stacktrace": [ "TypeError: Cannot read property 'id' of undefined", " at getcourse (/Users/admin/newProject/server4.js:116:17)",

with updateCourse is similar that id and topic are undefined

{ "data": { "updateCourseTopic": null } }

You can look at image enter image description here enter image description here Anyone help would be appreciated.

Thank you


Solution

  • A resolver can optionally accept four positional arguments: (parent, args, context, info).

    In order to work just need to specify first argument like this:

    function getcourse(_,args){
        var id=args.id;
        return coursesData.filter(course=>{
            return course.id==id
        })[0]
     
    
    }
    
    function updateCourseTopic (_,args){
        coursesData.map(course=>{
            if(course.id===args.id){
                course.topic=args.topic;
                return course
            }
        });
        return coursesData.filter(course=>course.id===args.id)[0]
        
    }