NodeJS API -> req.url.match initially only returned the else, but now only returns users[2]

import { createServer } from 'http';
const PORT = process.env.PORT;

const users = [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' },
{ id: 3, name: 'Jim Doe' }
];

const server = createServer((req, res) => {
if (req.url === '/api/users' && req.method === 'GET') {
res.setHeader('Content-Type', 'application/json');
res.write(JSON.stringify(users));
res.end();
} else if (req.url.match(/\/api\/users\/([0-9]+)/) && req.method === 'GET') {
const id = req.url.split('/')[3];
const user = users.find((user) => user.id === parseInt(id));
if (user) {
res.setHeader('Content-Type', 'application/json');
res.write(JSON.stringify(user));
res.end();
} else {
res.setHeader('Content-Type', 'application/json');
res.statusCode = 404;
res.write(JSON.stringify({ message: 'User not found' }));
res.end();
}
} else {
res.setHeader('Content-Type', 'application/json');
res.statusCode = 404;
res.write(JSON.stringify({ message: 'Route not found' }));
res.end();
}
});

server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
import { createServer } from 'http';
const PORT = process.env.PORT;

const users = [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' },
{ id: 3, name: 'Jim Doe' }
];

const server = createServer((req, res) => {
if (req.url === '/api/users' && req.method === 'GET') {
res.setHeader('Content-Type', 'application/json');
res.write(JSON.stringify(users));
res.end();
} else if (req.url.match(/\/api\/users\/([0-9]+)/) && req.method === 'GET') {
const id = req.url.split('/')[3];
const user = users.find((user) => user.id === parseInt(id));
if (user) {
res.setHeader('Content-Type', 'application/json');
res.write(JSON.stringify(user));
res.end();
} else {
res.setHeader('Content-Type', 'application/json');
res.statusCode = 404;
res.write(JSON.stringify({ message: 'User not found' }));
res.end();
}
} else {
res.setHeader('Content-Type', 'application/json');
res.statusCode = 404;
res.write(JSON.stringify({ message: 'Route not found' }));
res.end();
}
});

server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
No description
14 Replies
13eck
13eck3mo ago
I'm pretty sure that the error is in the line immidiately after the if condition:
// you have
const id = req.url.split('/')[3];
// should be
const id = req.url.split('/')[2];
// req.url.split("/") === ["api", "users", "3"]
// In JS arrays are 0 indexed, so while you have 3 items
// it's index 0, 1, and 2!
// you have
const id = req.url.split('/')[3];
// should be
const id = req.url.split('/')[2];
// req.url.split("/") === ["api", "users", "3"]
// In JS arrays are 0 indexed, so while you have 3 items
// it's index 0, 1, and 2!
CDL
CDLOP3mo ago
That's what I thought, but changing it to [2] now givs me the "User not found" message
13eck
13eck3mo ago
🤷
No description
13eck
13eck3mo ago
Wait, no, that's wrong. Shit You're right, since the url is actually /api/users/3. That first / makes it ["","api", "users", "3"]. So index 3 is correct
CDL
CDLOP3mo ago
Seems to be working now.. again, not entirely sure why it suddenly now works, I just changed the 2 back to a 3, saved, went back into postman and ran it again
CDL
CDLOP3mo ago
doesn't seem to work every time I change it.. is there a cooldown or request limit in postman I'm not seeing perhaps?
No description
No description
13eck
13eck3mo ago
What I'd do:
import { createServer } from 'http';
const PORT = process.env.PORT;

const users = [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' },
{ id: 3, name: 'Jim Doe' }
];

const server = createServer((req, res) => {
// ADD THIS LINE
consoel.log(req.url);
if (req.url === '/api/users' && req.method === 'GET') {
res.setHeader('Content-Type', 'application/json');
res.write(JSON.stringify(users));
res.end();
} else if (req.url.match(/\/api\/users\/([0-9]+)/) && req.method === 'GET') {
const id = req.url.split('/')[3];
const user = users.find((user) => user.id === parseInt(id));
// Also add this
console.log(`User ${user} found!`);
if (user) {
res.setHeader('Content-Type', 'application/json');
res.write(JSON.stringify(user));
res.end();
} else {
res.setHeader('Content-Type', 'application/json');
res.statusCode = 404;
res.write(JSON.stringify({ message: 'User not found' }));
res.end();
}
} else {
res.setHeader('Content-Type', 'application/json');
res.statusCode = 404;
res.write(JSON.stringify({ message: 'Route not found' }));
res.end();
}
});

server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
import { createServer } from 'http';
const PORT = process.env.PORT;

const users = [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' },
{ id: 3, name: 'Jim Doe' }
];

const server = createServer((req, res) => {
// ADD THIS LINE
consoel.log(req.url);
if (req.url === '/api/users' && req.method === 'GET') {
res.setHeader('Content-Type', 'application/json');
res.write(JSON.stringify(users));
res.end();
} else if (req.url.match(/\/api\/users\/([0-9]+)/) && req.method === 'GET') {
const id = req.url.split('/')[3];
const user = users.find((user) => user.id === parseInt(id));
// Also add this
console.log(`User ${user} found!`);
if (user) {
res.setHeader('Content-Type', 'application/json');
res.write(JSON.stringify(user));
res.end();
} else {
res.setHeader('Content-Type', 'application/json');
res.statusCode = 404;
res.write(JSON.stringify({ message: 'User not found' }));
res.end();
}
} else {
res.setHeader('Content-Type', 'application/json');
res.statusCode = 404;
res.write(JSON.stringify({ message: 'Route not found' }));
res.end();
}
});

server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Well shoot, you fixed it before I could tell you to add console logs :p Are you following a course? Is that where you're getting the code?
CDL
CDLOP3mo ago
Yeah it's Traversy media "node js crash course" from 1 year ago just a youtube vid
13eck
13eck3mo ago
Small rant, but a more "correct" version of REST would be to have the user ID (or any other variable) be a query param and not part of the URL itself. But that's because I've been taught more about what REST really is and not what people want it to be. The creator of the REST "archetechture" is very unhappy with what is being called "REST" but is acutally just SOAP using JSON :p That way, if query param get one item, else do other default action. But since you're following a course you should do what the teacher teaches
CDL
CDLOP3mo ago
Maybe he'll show that in a bit, to be fair it has gone from very basic to more advanced throughout this is just nodejs though, no express or anything
13eck
13eck3mo ago
I highly doubt it. 99% of anyone teaching anything API-related uses hardcoded URL wildcards and totally ignore query params. Makes me sad That I know. And I'm happy to see that, at least. "Let's learn Nodejs! Step 1: NPM install 16 packages!" is not how one learns Nodejs, it's how one learns to install packages :p
CDL
CDLOP3mo ago
haha yeah, all we've done is nodemon I do like traversy, he doesn't tend to overcomplicate things
13eck
13eck3mo ago
And that's not so much a package you use in prod, it's just so you don't have to restart your server all the time I hope I can get to that stage one day soon. Provide a well-written Nodejs course. Teach the language and not the package ecosystem Anyway, I'll get off my soapbox and let you get back to Brad! Good luck on your Nodejs journey! Feel free to ping me in any question thread you make 😁
CDL
CDLOP3mo ago
Thanks Beck!

Did you find this page helpful?