0

I'm trying to build a website for a school project. I setted up everything but i get the error "Data.map is not a function". Actually i'm not an expert and i'm just trying to understand and copy the code that the teacher gave us (we did almost nothing in node.js).

I've built the server using node.js

const express = require("express");
const app = express();
const process = require("process");
const bodyParser = require("body-parser");

let serverPort = process.env.PORT || 5000;

app.use(express.static(__dirname + "/public"));

app.set("port", serverPort);

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.get('/doctors', function(req,res){
    var config = require('./doctor.json');
    res.send(JSON.stringify(config));
})

/* Start the server on port 3000 */
app.listen(serverPort, function() {
    console.log(`Your app is ready at port ${serverPort}`);
});

When i connect to the doctor page, i load a JSON file with all the doctors and i send it back to the client. Here is the JSON

[{
        "id": 0,
        "born": 2010,
        "tag": "cat",
        "name": "Eleanore"
    }, {
        "id": 1,
        "born": 2010,
        "tag": "dog",
        "name": "Katelin"
    }, {
        "id": 2,
        "born": 2012,
        "tag": "dog",
        "name": "Shea"
    }, {
        "id": 3,
        "born": 2011,
        "tag": "cat",
        "name": "Stephen"
    }, {
        "id": 4,
        "born": 2011,
        "tag": "cat",
        "name": "Rosanne"
    }, {
        "id": 5,
        "born": 2011,
        "tag": "cat",
        "name": "Alexa"
    }
]

Then i load the JSON and i would like to create dynamically items. Here is my client side code:

$.get('/doctors', function (data) {
    $("<div class='row' id='dottori' ></div>").appendTo(".team");

    data.map(addElement);
});

function addElement(doctor){
    console.log("Adding doctor");
    $("#dottori").append('<p> '+doctor.name+'</p>');

I keep getting this error, even if i stringify the json file (the same thing that my professor did), you can find the original code here: https://bitbucket.org/polimi-hyp-2017-10173412/polimi-hyp-2018-project/src/master/

Stphane
  • 3,368
  • 5
  • 32
  • 47
Mattia Surricchio
  • 1,362
  • 2
  • 21
  • 49

2 Answers2

1

Data received by $.ajax(), and any of it's wrapper methods, will receive the response as text. If you want to process this response as an object parsed from the json, you will have to do one of a few things.

You can parse the data yourself

var stuff = JSON.parse(data);

You can manually parse it yourself.

You can make jQuery parse it explicitly

$.ajax({ url: ..., contentType: 'json' })

Providing the contentType parameter with the value of json will tell jQuery that the response should be json and it should auto parse it before giving it to a callback.

You can make jQuery parse it implicitly

This is done by setting the Content-Type: application/json on the response. When jQuery gets the response, it will inspect this header to try to intelligently guess what the response is and handle it.

According to this stack overflow post, Proper way to return JSON using node or Express, you can do so in node by...

res.setHeader('Content-Type', 'application/json');
Taplar
  • 24,788
  • 4
  • 22
  • 35
  • This makes everything much clearer! I've solved my problem with map function parsing my data item. I read here ( https://stackoverflow.com/questions/30803168/data-map-is-not-a-function ) that map doesn't work with objects, but what .parse does is to create an object ( https://www.w3schools.com/js/js_json_parse.asp ). I'm a bit confused – Mattia Surricchio May 31 '18 at 15:06
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map `map` is an array method, which arrays are objects. Your json outer most token is `[]` so parsing it creates an array, so you can map it. If the outer most token was `{}`, it would create an object that was not an array, and map doesn't work with plain objects, as stated in that linked post. @MattiaSurricchio – Taplar May 31 '18 at 15:08
  • I got it! Thank you, wish my prof was as clear as you – Mattia Surricchio May 31 '18 at 15:13
1

To map the json object... data must be an object... Not a string.

It was received as a string... So you just have to parse it to an object.

Here, it is chained with the .map() method:

JSON.parse(data).map(addElement);

But you could have done (same thing):

var dataObj = JSON.parse(data);
dataObj.map(addElement);

Remember the useful trick to check the type of a variable, mentionned by taplar:

console.log(typeof(variable-to-check));

typeof() is a good debugging trick... And it is sometimes necessary to have it in some conditions to avoid errors (like if the script uses different sources).

;)

Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64