0

I'm trying to code a Webserver in plain NodeJS with http. What i'm trying to do is when you have the url /add/ whatever is after the /add/ would be added to a array, and showen on / but its not saving the array, and resets it when i add something new. Can someone explain what i did wrong?

Sorry that my code is a bit messy.

Index.js:

const http = require('http');
const $conf = require('./config.json');

http.createServer((req, res) => {

    let $list = [];

    const url = req.url;
    const $req = url.split('/');
    const $req_q = url.split('?');

    if (req.url == "/"){
        res.write($list.toString());
    } else if (req.url == `/add/${$req[2]}`){

        $list.push($req[2])
        console.log($list)
        res.write(`ADDED ${$req[2]}`)

    } else {
        res.write('Error');
    }
    res.end();
}).listen($conf.port);

Config.json:

{
    "port": 80
}

When i goto /add/hi i get "ADDED hi".

Then go back to / and get nothing.

1
  • The console.log in the else if block does it print to console? Commented Apr 10, 2021 at 6:29

2 Answers 2

1

A NodeJS webserver executes a route (e.g '/' or '/add') on-demand. That means that everything inside the function is executed from scratch on every request.

Therefore your $list variable gets initialized everytime you call a route and you can't see the result on the screen.

You can fix it by moving the variable to the global scope.

const http = require('http');
const $conf = require('./config.json');

let $list = []; // Now this value is persisted between requests

http.createServer((req, res) => {
    const url = req.url;
    const $req = url.split('/');
    const $req_q = url.split('?');

    if (req.url == "/"){
        res.write($list.toString());
    } else if (req.url == `/add/${$req[2]}`){

        $list.push($req[2])
        console.log($list)
        res.write(`ADDED ${$req[2]}`)

    } else {
        res.write('Error');
    }
    res.end();
}).listen($conf.port);
Sign up to request clarification or add additional context in comments.

1 Comment

I'm not sure whether it would be obvious or not to OP but it would at least be beneficial to point out that this $list is shared between all clients accessing the webserver and is not separate for each client.
0

The main reason is the $list array is initialized every time there is a new request. So, there can be two ways of doing this at the moment.

  1. Create a variable outside this route scope so you can access the previous value. (this variable will be shared for every request/client)
  2. Another and more efficient way is you can store the value more efficiently using node-json-db, as there might be thousands of request for which you might need to save this data and it won't be efficient at that time. You can use node-json-db.

Sample code:

import { JsonDB } from 'node-json-db';
import { Config } from 'node-json-db/dist/lib/JsonDBConfig'

// The first argument is the database filename. If no extension, '.json' is assumed and automatically added.
// The second argument is used to tell the DB to save after each push
// If you put false, you'll have to call the save() method.
// The third argument is to ask JsonDB to save the database in an human readable format. (default false)
// The last argument is the separator. By default it's slash (/)
var db = new JsonDB(new Config("myDataBase", true, false, '/'));

// Pushing the data into the database
// With the wanted DataPath
// By default the push will override the old value
db.push("/test1","super test");

// Get the data from the root
var data = db.getData("/");

// From a particular DataPath
var data = db.getData("/test1");

// If you try to get some data from a DataPath that doesn't exists
// You'll get an Error
try {
    var data = db.getData("/test1/test/dont/work");
} catch(error) {
    // The error will tell you where the DataPath stopped. In this case test1
    // Since /test1/test does't exist.
    console.error(error);
};

There are several other operations you can perform for that you should check its documentation.

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.