the chad
the chad

Reputation: 403

Why am I not getting a JSON object in the response from my local node.js/express server?

-- The background to situation --

I'm making an e-form signup for a client of our business marketing strategy service blah blah blah...

the form is done and looks great. now I need to hook it up to the existing API of the service our business uses to hold/sort/query/etc the submitted information.

I'm a very junior developer and the API is very complex. I just want to make sure my ES6/javascript is in proper working order. The ajax calls are working, no bugs in my code etc. So it seemed the quickest easiest thing to do in order to test things was just make a simple local server so I can test my calls get everything working BEFORE I start going through tons of API documentation and getting it properly hooked up to our service. The first call seems to work fine. But I couldn't get my lil' baby server to "respond" properly with some static info to parse through. I'm primarily a front-end developer, but I'm obsessed with figuring this little server problem out at this point... So help would be VERY appreciated.

-- the fetch request --

fetch('http://localhost:4000/send-zip')
            .then( 
                (response) => {
                    response.json(),
                    console.log('begin fetch to local server'),
                    console.log(response),
                    populate_store_selector(response)
                })
            .catch(
                (error)=> console.log('basic fetch request failed' + error)
            )

-- that other function in case people ask --

(it is simply meant to iterate through and populate an html input type="select" )

function populate_store_selector(arg) {
    for (i of arg) {
        let new_option = document.createElement('option')
        new_option.innerHTML = arg[i]
        select_shop.appendChild(new_option)
    }
}

-- my little baby server --

const express = require('express')
const server = express()

server.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

server.get('/send-zip', function (req, res) {
    res.send({ "options": ['option1', 'option2', 'option3'] })
})

server.listen(4000, () => console.log('mock server listening on port 4000!'))

the server works just fine and does it's job OTHER than I'm never able to get it to send a JSON object back :( I've tried lots of things so far. Honestly it doesn't matter as my request on the front end works just fine but I'm too obsessed to let this go right now...

-- what the console.log() shows in the browser --

begin fetch to local server

main.js:104 

Response {type: "cors", url: "http://localhost:4000/send-zip", redirected: false, status: 200, ok: true, …}body: (...)bodyUsed: trueheaders: Headers {}ok: trueredirected: falsestatus: 200statusText: "OK"type: "cors"url: "http://localhost:4000/send-zip"__proto__: Response

main.js:108 

basic fetch request failedTypeError: arg is not iterable

Upvotes: 1

Views: 2639

Answers (1)

Lionel
Lionel

Reputation: 136

You might try parsing the response after the response stream completes, and then taking action on the data.

fetch('http://localhost:4000/send-zip')
        .then( 
            (response) => {
                return response.json();
        }).then(
            (response_json) => {
                console.log('begin fetch to local server'),
                console.log(response_json),
                populate_store_selector(response_json)
            })
        .catch(
            (error)=> console.log('basic fetch request failed' + error)
        )

The reason that you need to include the additional .then step and return response.json() is that the http response object returns the body data as a readable stream.

The JSON function is designed to accept a stream and convert it into JSON after the stream completes. This may feel somewhat unintuitive for anyone familiar with axios or other AJAX convenience libraries, as that part of the process is abstracted from view.

What this basically means is that after you wait for the response http object to be returned, you need to wait again for the stream to also complete.

There are a few different methods available which can act upon a stream upon completion including arrayBuffer,blob, and text (there are a few more I think as well). Usually they tend to convert the data into the format you prefer after it has completed.

Upvotes: 5

Related Questions