1

I am learning JS. I was working with Mongoose and I wanted do pass a function and parameter(s) to a callback, but I have to use call() instead.

// Car is a model. Using Express in Node.js
express.Router().route('/')
    .get((req,res,next)=>{
        print(res,next,Cars.find)
    })

const print = async(res,next,func,param1={})=>{
    try {
        const cars = await func.call(Cars,param1)
        res.statusCode = 200;
        res.setHeader('Content-Type', 'application/json');
        res.json(cars);
    } catch (err)
        next(err);
}

It does not work for me when I simply do func(param1) inside print(...), which returns this error.

MongooseError: `Model.find()` cannot run without a model as `this`.
Make sure you are calling `MyModel.find()` where `MyModel` is a Mongoose model.

Could you please explain why that is and when I need to use apply()/call() to pass in this? In this context of Mongoose and in general?

Also I'm a bit confused on next() and next(err). Documentation says it's just so the program can "skip" the error in some sense and I can visibly see that. But is it like a callback function that we can modify or it's something built in?

EDIT: Im looking at How to access the correct `this` inside a callback and is it because somehow the object is not passed into print()?

Jonas
  • 121,568
  • 97
  • 310
  • 388
okzoomer
  • 308
  • 1
  • 11
  • That won't work. `func_param1 = {}` isn't iterable – CertainPerformance Aug 05 '21 at 02:11
  • @CertainPerformance oh I see I used call() instead of apply() in my dev code. But the syntax of apply() or call() is not what I'm asking about. I changed it to call(). Thanks. – okzoomer Aug 05 '21 at 05:08
  • 1
    You shouldn't use `call` here - now your `print` function works only for the `Cars` model. Instead, use the simple `await func();`, but pass `Cars.find.bind(Cars, {})` or `() => Cars.find({})` as the callback. – Bergi Aug 06 '21 at 17:13
  • thanks @Bergi. Because for different http requests I'll be using different methods, so I'll call `Cars.find()` in the parent function `get()` instead. Much easier to debug that way. But this is definitely good to know as a tool in my toolbox. – okzoomer Aug 06 '21 at 18:57

1 Answers1

0

In js, this is determined at run time and refers to what runs the method. If the method is defined by or is called in an arrow function then this bubbles up to the parent function. In this case this would have been get() had I not used call(). So I was correct in a sense that the parent object Cars was not passed along with Cars.find().

okzoomer
  • 308
  • 1
  • 11