2

I am writing a server with two functions, one using the output of another function. When the server runs, it gives an error:

TypeError: Cannot read property 'Symbol(Symbol.toStringTag)' of undefined
    at isAsync (/Users/charles/Documents/Router/node_modules/async/dist/async.js:228:32)
    at wrapAsync (/Users/charles/Documents/Router/node_modules/async/dist/async.js:232:12)
    at nextTask (/Users/charles/Documents/Router/node_modules/async/dist/async.js:5308:20)
    at Object.waterfall (/Users/charles/Documents/Router/node_modules/async/dist/async.js:5320:5)
    at /Users/charles/Documents/Router/routes/yelp.js:46:15
    at /Users/charles/Documents/Router/node_modules/mongojs/lib/cursor.js:59:24
    at handleCallback (/Users/charles/Documents/Router/node_modules/mongojs/node_modules/mongodb/lib/utils.js:120:56)
    at /Users/charles/Documents/Router/node_modules/mongojs/node_modules/mongodb/lib/cursor.js:683:5
    at handleCallback (/Users/charles/Documents/Router/node_modules/mongojs/node_modules/mongodb-core/lib/cursor.js:171:5)
    at setCursorDeadAndNotified (/Users/charles/Documents/Router/node_modules/mongojs/node_modules/mongodb-core/lib/cursor.js:505:3)

The code is

const express = require('express');
const router = express.Router();

const request = require('request-promise-lite');
const async = require('async');

router.get('/yelp', function(req, res, next) {
  db.input.find({}, {
      term: 1,
      location: 1,
      _id: 0
    })
    .limit(1).sort({
      $natural: -1
    }, function(err, input) {
      if (err) {
        res.send(err)
      }

      console.log(input);
      async.waterfall([yelpSearch(input[0]), googleSearch],
        function sendJson(err, restaurants) {
          console.log("waterfall starting");
          if (err) res.send(err);
          res.json(restaurants);
        })
    })
});

// Yelp API call
const yelpSearch = function(input, cb) {
  const client = yelp.client(apiKey);
  client.search(input)
    .then(response => {
      console.log(response.jsonBody.businesses);
      cb(null, response.jsonBody.businesses);
    })
    .catch(e => {
      console.log(e);
    });
}

// Google API call
const googleSearch = function(restaurants, cb) {
  console.log("google starts")
  var apiKey = google_apiKey;
  var cseKey = cseID;
  restaurants.forEach(function(restaurant) {
    var keyWord = restaurant.name + restaurant.city + restaurant.state;

    var googleURL = "https://www.googleapis.com/customsearch/v1?key=" + apiKey +
      "q=" + keyWord +
      "&searchType=image" +
      "&cx" + cseKey +
      "&count=5" +
      "&safe=medium";

    var imageURLs = [];
    request.get(googleURL, {
      json: true,
      headers: {
        'User-Agent': 'thaorell'
      }
    }).then(function(response) {
      response.items.forEach(function(item) {
        imageURLs.append(item.link)
      });

      restaurant.append(imageURLs);
      console.log(imageURLs);
    })
  })
  cb(null, restaurants)
};

Does anyone have any experience in this? The error is on the line with: async.waterfall([yelpSearch(input[0]), googleSearch]. I am using Yelp API to search for restaurants then for each restaurant, I would like to fetch the Google Search for images of that restaurant.

7
  • What line of your code does that error occur at? Apr 23, 2018 at 5:27
  • Are you missing an import for async? caolan.github.io/async/docs.html
    – Gerik
    Apr 23, 2018 at 5:35
  • @CertainPerformance: I edited it in the question. It occurred at async.waterfall() Apr 23, 2018 at 5:38
  • @Gerik: no I didn't Apr 23, 2018 at 5:38
  • Hm, it's saying async is not defined and the reason why it wouldn't be defined is because it hasn't been imported, created, or referenced properly. Can you show us how it's being imported/included? I don't see it in the code above.
    – Gerik
    Apr 23, 2018 at 5:43

2 Answers 2

1

I guess, you are passing arguments to the first function in the waterfall wrongly, it should be:

async.waterfall([
    async.constant(input[0]),
    yelpSearch,
    googleSearch
], function sendJson(err, restaurants) {
    // ...
});
1
  • That made it. do you know why I couldn't parse the input directly into the function? Apr 23, 2018 at 16:47
1

Both yelpSearch and googleSearch are consts; they doesn't get hoisted. So, at the time you call async.waterfall([yelpSearch(input[0]), googleSearch],, the functions does not exist yet, so it fails. Declare them above router.get instead (or change them to hoisted function declarations).

1
  • It doesn't work. Also, I think it fails inside yelpSeach() Apr 23, 2018 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.