Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
103 views
in Technique[技术] by (71.8m points)

javascript - Getting error CreateListFromArrayLike called on non-object when trying to use .apply()

I've created a simple little route parsing function so that I can keep my code clean and easily maintainable, this is the little function that gets ran when the app starts up and parses the config.json file and binds the appropriate methods and request paths:

const fs = require('fs');
const path = require('path');
module.exports = function(app, root) {
  fs.readdirSync(root).forEach((file) => {
    let dir = path.resolve(root, file);
    let stats = fs.lstatSync(dir);
    if (stats.isDirectory()) {
      let conf = require(dir + '/config.json');
      conf.name = file;
      conf.directory = dir;
      if (conf.routes) route(app, conf);
    }
  })
}

function route(app, conf) {
  let mod = require(conf.directory);

  for (let key in conf.routes) {
    let prop = conf.routes[key];
    let method = key.split(' ')[0];
    let path = key.split(' ')[1];

    let fn = mod[prop];
    if (!fn) throw new Error(conf.name + ': exports.' + prop + ' is not defined');
    if (Array.isArray(fn)) {
      app[method.toLowerCase()].apply(this, path, fn);
    } else {
      app[method.toLowerCase()](path, fn);
    }
  }
}

The problem I have is some times I need to pass in multiple arguments to an express router, e.g. in the case of using passport something like this:

exports.authSteam = [
  passport.authenticate('facebook', { failureRedirect: '/' }),
  function(req, res) {
    res.redirect("/");
  }
];

So I figure I can just pass them as an array, and then parse them into the router appropriately, my config for example looks like this:

{
  "name": "Routes for the authentication",
  "description": "Handles the authentication",
  "routes": {
    "GET /auth/facebook": "authFacebook",
    "GET /auth/facebook/return": "authFacebookReturn"
  }
}

The only problem is I'm getting this error:

     app[method.toLowerCase()].apply(this, path, fn);
                                ^

TypeError: CreateListFromArrayLike called on non-object

if I console.log(fn) I see [ [Function: authenticate], [Function] ]

I'm not exactly sure what I am doing wrong, any information would be great thanks.

question from:https://stackoverflow.com/questions/41354099/getting-error-createlistfromarraylike-called-on-non-object-when-trying-to-use-a

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You need to send the params as an array, like this:

app[method.toLowerCase()].apply(this, [path, fn]);

If you want to send an arguments list you need to use call:

app[method.toLowerCase()].call(this, path, fn);

Source: call, apply


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...