Ychop
Ychop

Reputation: 27

Access array component in express/REST

this is my first question in this forum ever, so pls be kind to me if i did something wrong.

first i will show you my code:

const express = require('express');
const fs = require('fs');
const app = express();
const port = 8081;
const filename = __dirname + '/jokes.json';

app.use(express.json());

app.get('/jokes/:id', (req, res) => {
    fs.readFile(filename,"utf8", (err,data)=>{
        if(err){
            res.send("Error:"+ err);
        }else{
            const jokes = JSON.parse(data)[req.params.id];
            res.writeHead(200, {"Content-Type": "application/json"});
            res.end(JSON.stringify(jokes));  
        }      
    });
});

the Jokes.json file looks like this:

 {
 "jokes" : [
    {   "id": "1", 
        "title": "Zwei Bomben im Keller", 
        "text": "Sind zwei Bomben im Keller, sagt die eine zur anderen:\"Lass mal hochgehen.\" "
    },
    {   "id": "2", 
        "title": "Mönche in Asien", 
        "text": "Hoch in den japanischen Bergen fragt der Zen-Schüler seinen Meister: „Meister Aikodo, warum denken die Europäer, dass wir alle gleich aussehen? - Antwortet der Meister: „Ich bin nicht Meister Aikodo."
    },
    {   "id": "3", 
        "title": "Privatsphäre", 
        "text": "Natürlich müsste ich mal die Fenster putzen, aber Privatsphäre ist auch wichtig."
    },
    {   "id": "4", 
        "title": "Fieser Peter", 
        "text": "Susanne: Hallöchen! Peter: Hallöchen! - Susanne: Wie geht es dir! Peter: Wie geht es dir! - Susanne: Äffst du mich nach?! Peter: Äffst du mich nach?! - Susanne: Ich bin hässlich (grinst) Peter: Ja, das stimmt."
    },
    {   "id": "5", 
        "title": "Teewitz", 
        "text": "Welchen Tee sollte man besser nicht trinken? - TNT"
    }]
 }

So i'm trying to access a specific joke in my jokes array via the id component in the jokes array. But the problem is, when i start the server and i put "http://localhost:8081/jokes/1" in the URL, then nothing is shown at the website. So how can i do this, or is this even possible?

don't mind the Strings in the Jokes array, they are german, i'm german so my english is pretty weak, nonetheless i hope you can understand my problem/question and i'm thankfull for every hint/help you guys could give me :)

Edit: Thanks to you guys the Problem is solved (see below :) )

Upvotes: 0

Views: 141

Answers (3)

Don Foumare
Don Foumare

Reputation: 464

The issue is that you try to access an object property that does not exist and thus it returns undefined. The square brackets [..] allow us to access an objects property by its name (key) - see Property accessors. In your example (http://localhost:8081/jokes/1) the value of req.params.id (which is actually a string) is used to access a property with the name "1".

For example:

let data = '{ "1": ["some", "property"] }'

// this 
let jokes = JSON.parse(data)[req.params.id];

// would be the same as
jokes = JSON.parse(data)["1"];

console.log(jokes)

// Output: 
// ["some", "property"]

In your case however JSON.parse(data) returns an object with the sole property jokes, which is the actual array containing the jokes. You can access it either with .jokes or ['jokes']. Now to get the joke that corresponds to req.params.id you could iterate over the array and check the id property of each one.

For example:

// parse the contents of 'jokes.json' (data) to an object
const jokes_obj = JSON.parse(data);

// get the `jokes` property (the array)
const jokes_arr = jokes_obj.jokes;
            
// search for the item whose id corresponds to req.params.id
jokes_arr.forEach(element => {
    if(element.id == req.params.id) {
        res.writeHead(200, {"Content-Type": "application/json"});
        return res.end(JSON.stringify(element));
    }
});

// return error message in case no joke matches the ID
return res.end('{ "msg": "ID nor found" }');

Upvotes: 0

theusaf
theusaf

Reputation: 1802

You are missing a .jokes in your code. JSON.parse(data)[req.params.id] would be undefined, unless you GET /jokes/jokes because your JSON file's top-level object only has the key "jokes," which contains all the jokes. To fix this, add .jokes after JSON.parse(data):

const express = require('express');
const fs = require('fs');
const app = express();
const port = 8081;
const filename = __dirname + '/jokes.json';

app.use(express.json());

app.get('/jokes/:id', (req, res) => {
    fs.readFile(filename,"utf8", (err,data)=>{
        if(err){
            res.send("Error:"+ err);
        }else{
            const jokes = JSON.parse(data).jokes[req.params.id];
            res.writeHead(200, {"Content-Type": "application/json"});
            res.end(JSON.stringify(jokes));  
        }      
    });
});

Upvotes: 1

João Marcello
João Marcello

Reputation: 38

welcome to StackOverflow. I'm not much of a veteran here, but i'll try to help you.

Import the json file like this: const { jokes } = require('...YourPath/jokes.json')

And then make your app.get() like this:

app.get('/jokes/:id', (req, res) => {
   try {
      const { id } = req.params

      const filteredJokes = jokes.filter(joke => joke.id === id)

      res.json(filteredJokes)
   }
   catch(err) {
      console.log(err)
   }
}

Upvotes: 0

Related Questions