0

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 :) )

3 Answers 3

1

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));  
        }      
    });
});
Sign up to request clarification or add additional context in comments.

4 Comments

Damn, that worked, Thank you! your my savior!! if you want i can translate one joke for you, so you will have maybe a laughter at least :3 love you <3
Since jokes is an array, JSON.parse(data).jokes[req.params.id] will access the second item in that array if req.params.id == 1. This will give you the wrong result if your jokes list begins with any id other than 0 or if the ids in the list are not consecutive and without breaks. Instead you should iterate over the array and check which element has an id of req.params.id, like I showed in my answer.
Yeah i noticed that too, i did somethin like this JSON.parse(data).jokes[req.params.id -1] to solve this.
@Ychop I would suggest you to not alter the 'intention' or 'meaning' of a variable and either change the parameter from :id to :index (if you want to use it as an index) or use the id the proper way. It doesn't take much effort to do it properly. And it doesn't make much sense to expect an ID at the API when you use it as an index later on.
0

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)
   }
}

Comments

0

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" }');

Comments

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.