0

I am trying to make API call from Node.js Expressjs. API call is working fine however after parsing the response to JSON, when I try to access different fields it gives me an error. I try to log the type of one element of the JSON object to console. First it says Object and then it says undefines (or if try to log the content itself, it gives me an error).

var request = require('request');

const app = express();


 //For serving static pages
// app.use(express.static('./static'))
app.get('/', (req, res) =>{
    res.send('You have successfully contacted the API')
});

app.get('/:ticker', (req, res) => {
    var requestOptions = {
        'url': 'https://api.tiingo.com/tiingo/daily/' + req.params.ticker + '/prices?startDate=2019-01-02&token=74e7c9d22c2ffe8e9b5643edc2ef48bbddc6e69e',
        'headers': {
            'Content-Type': 'application/json'
            }
    };
    
    request(requestOptions,
        function(error, response, body) {
            result = JSON.parse(body);
            console.log('The type is ' + typeof (result[0].date)) //This statement prints different results twice
            res.send(result);
            
        }
    );   
});

app.listen(process.env.PORT || 3000)

Terminal says:

The type is string

D:\Web Dev Bootcamp\NodeJS-Tutorial\index.js:24
            console.log('The type is ' + typeof (result[0].date))
                                                           ^

TypeError: Cannot read property 'date' of undefined
    at Request._callback (D:\Web Dev Bootcamp\NodeJS-Tutorial\index.js:24:60)
    at Request.self.callback (D:\Web Dev Bootcamp\NodeJS-Tutorial\node_modules\request\request.js:185:22)
    at Request.emit (events.js:314:20)
    at Request.<anonymous> (D:\Web Dev Bootcamp\NodeJS-Tutorial\node_modules\request\request.js:1154:10)
    at Request.emit (events.js:314:20)
    at IncomingMessage.<anonymous> (D:\Web Dev Bootcamp\NodeJS-Tutorial\node_modules\request\request.js:1076:12)
    at Object.onceWrapper (events.js:420:28)
    at IncomingMessage.emit (events.js:326:22)
    at endReadableNT (_stream_readable.js:1223:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) [nodemon] app crashed - waiting for file changes before starting...
6
  • 1
    It seems pretty clear that sometimes when you do the request, result[0] is undefined so then result[0].date is a TypeError. You will have to either figure out why that is or check to see if result and result[0] are valid before you try to use them. Since you are varying req.params.ticker from one request to the next, perhaps it doesn't work for some ticker values. Commented Oct 19, 2020 at 23:50
  • I would suggest that you also add console.log(req.params.ticker) to your request handler as you are probably getting a value you do not want. For example, if this was coming from a browser, you may be getting favicon.ico because your app.get('/:ticker', ...) is a wildcard route that matches any top level request that is sent to your server. This is often problematic. Commented Oct 19, 2020 at 23:53
  • It is not giving me different results on different calls, but different results on 'same' call. The first output that it gives is perhaps because of pre-flight CORS request and second time when it makes the request again, as explained here [stackoverflow.com/questions/54957409/… Commented Oct 19, 2020 at 23:59
  • btw, request package was deprecated over 8 months ago Commented Oct 20, 2020 at 0:04
  • 1
    CORS pre-flight does not to a GET request, it does an OPTIONS request so I'm not sure what you're talking about there. Just add a bunch of debugging to your request handler so you can see exactly what URL you're requesting and exactly what response you're getting back. This is BASIC debugging which only you can do and needs to be done before we can help you. Commented Oct 20, 2020 at 0:10

2 Answers 2

2

Run a quick console.log(result) to make sure that result is being stored as an Array. I suspect that when you are parsing the JSON it is storing result as an object.

Sign up to request clarification or add additional context in comments.

3 Comments

Just tried you suggestion and observed something strange. It logs the whole result JSON object and then it makes another call automatically and logs this: { detail: "Error: Ticker 'FAVICON.ICO' not found" }
@RizwanMalik - Yeah, exactly as my comment above says. Your route is catching every request and browsers automatically ask for /favicon.ico on a new website.
@Harry Pretel - you're exactly right :) Hopefully Rizwan Malik understands what you tried to say.
-1

Figured out what the issue was. Actually express was making a request for favicon.ico by itself and during that request apparently result variable was undefined. I simply set up another route for handling favicon request as suggested [here][1]. Now the code is simply logging the result once and I am able to access the fields of JSON object properly.

Edit: as pointed out by a contributor, its the browser thats making the favicon request and 'not' the express. [1]: Node Express "favicon.ico" not found error

3 Comments

It's NOT express making that request for /favicon.ico. It's your browser client. Your problem is that you're not checking the input or the output before using it and you have a route app.get('/:ticker', ...) that catches EVERY possible top level URL. Garbage in, garbage out. You need to be verifying proper inputs, then verify proper outputs before trying to use them. This is expected defensive coding that all servers should do.
Note, you can still make your server crash by just sending it a URL that has an invalid ticker symbol. You have to code much more defensively.
You're fundamentally misunderstanding many things here :( 1) as jfriend00 pointed, out, the favicon.ico request is coming from your browser, not your app. 2) You expect the HTTP response to be JSON, and you set result = JSON.parse(body); accordingly. That's OK. But if you don't get a JSON response ...or if the JSON doesn't contain "date" ... then you're going to get undefined when you try to access result[0].date!!! Which was the root cause behind your original question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.