I'm setting up routes for in my express server. As I tried to use it with a route paramter, I stumbled upon a problem:
router.get('/edit/:id', (req, res) => {
res.sendFile(rootPublic + '/pages/recipes/edit.html')
})
Is it possible to somehow send the data of the object I want to edit with the response? Or is it only possible to use the id as a query parameter and read the data on document load?
Related
I am creating a MERN app that adds meta tags to React pages without SSR. So, I need to read the query inside the main file of the server and pass the appropriate metadata content to each page.
I am using this in the server.js file:
const indexPath = path.resolve(__dirname, 'build', 'index.html');
// static resources should just be served as they are
app.use(express.static(
path.resolve(__dirname, 'build'),
{ maxAge: '30d' },
));
// here we serve the index.html page
app.get('/*', (req, res, next) => {
fs.readFile(indexPath, 'utf8', (err, htmlData) => {
if (err) {
console.error('Error during file reading', err);
return res.status(404).end()
}
// get post info
const postId = req.query.id;
const post = getPostById(postId);
if(!post) return res.status(404).send("Post not found");
// inject meta tags
htmlData = htmlData.replace(
"<title>React App</title>",
`<title>${post.title}</title>`
)
.replace('__META_OG_TITLE__', post.title)
.replace('__META_OG_DESCRIPTION__', post.description)
.replace('__META_DESCRIPTION__', post.description)
.replace('__META_OG_IMAGE__', post.thumbnail)
return res.send(htmlData);
});
});
Here the getPostById is statically defined in a file. But I want to fetch it from my db.
My file structure is:
server.js
controllers
- posts.js
routes
- posts.js
I've separated the logic from route. So my routes/posts.js file looks like:
import { getPost, createPost } from '../controllers/posts.js';
const router = express.Router();
router.get('/', getPost);
router.post('/', createPost);
export default router;
So, in order to dynamically pass the meta content, I need to read the API endpoint for each request and pass the appropriate data. For this, I need to call the endpoints directly inside my node project. How to do that?
I'd appreciate any help. Thank you.
If you really want to call your own http endpoints, you would use http.get() or some higher level http library (that is a little easier to use) such as got(). And, then you can make an http request to your own server and get the results back.
But ... usually, you do not make http requests to your own server. Instead, you encapsulate the functionality that gets you the data you want in a function and you use that function both in the route and in your own code that wants the same data as the route. This is a ton more efficient than packaging up an http request, sending that request to the TCP stack, having that request come back to your server, parsing that request, getting the data, forming it as an http response, sending that response back to the requester, parsing that response, then using the data.
Instead, if you have a common, shared function, you just call the function, get the result from it (probably via a promise) and you're done. You don't need all that intermediate packaging into the http request/response, parsing, loopback network, etc...
I'm attempting to make a request to an API to get a users' avatar. This is the code I have, however it's returning a "player is not defined" error.
app.get(`/api/avatar/${player}`, function(req, res) {
res.redirect(`http://cdn.simulping.com/v1/users/${player}/avatar`);
});
Essentially, if the URL is /api/avatar/3925 it would send them to http://cdn.simulping.com/v1/users/3925/avatar.
Assuming you're using Express.JS for the routing, the correct way for doing that is:
app.get('/api/avatar/:id', function(req, res) {
res.redirect(`http://cdn.simulping.com/v1/users/${req.params.id}/avatar`);
})
Assuming you are using Express routing, then you would need to utilise route parameters.
The Express documentation provides:
Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the req.params object, with the name of the route parameter specified in the path as their respective keys.
In this case:
Route path: /api/avatar/:player
Request URL: http://localhost:3000/api/avatar/3925
req.params: { "player": "3925" }
The working code:
app.get('/api/avatar/:player', function(req, res) {
res.redirect(`http://cdn.simulping.com/v1/users/${req.params.player}/avatar`);
});
You can read more about it in the Route Parameters section of the Express Routing Guide.
While running an express server, what is the proper way to redirect incoming requests?
I have two routes: POST and UPDATE. The POST route is used to create new item to database and UPDATE increases votes in the item.
I would like to use middleware(?) to redirect my requests based on db content:
if element with req.param does exist => redirect to UPDATE to handle upvotes
else create new element => redirect to POST to handle creation
I think a simple way of doing this could be:
const middleware = (req, res, next) => {
req.param.name ? req.url = '/POST' : req.url = '/UPDATE'
next();
}
, Or you can redirect your request to other routes.
const middleware = (req, res, next) => {
req.param.name ? res.redirect('/POST') : res.redirect(/UPDATE')
next();
}
Also, you can make dynamic routes if you have many routes involved doing different things. You can check this: How to call an api from another api in expressjs?
I am attempting to build a single page app using Express.js. On my index.html page, I have a basic form, which upon submit will make a request to an API, retrieve the data, parse it, and then I want to render the parsed data as a list of links. Right now I am able to render the index page, and I can make the submission call to the API from the form that I added to the page. What I am confused about is how to properly redirect the data I get from the API call and then render it on the same page. I've built simple apps using Express before where there were multiple views, but never a single page app. For those apps, I know that for the response you could call something like res.render('name of view to render', data), but that is not working in this case. I've tried to find some solutions through this site and via the Express docs, but I have not seen anything that didn't also include using another framework like Angular. For the purposes of this app, I need to not include any additional frameworks, and I am a bit lost.
My function for calling the API looks like this right now. When it is called, I am directed to a page that just has the json displayed
app.use(express.static(path.join(__dirname, '/public')));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use('/', express.static(path.join(__dirname, 'public')));
app.get('/search', function(req, res) {
var title = req.query.movieTitle;
var url = 'http://www.omdbapi.com/?s=' + title;
request(url, function (err, response, body) {
var results = JSON.parse(body);
var movieTitles = results.Search;
console.log(movieTitles);
res.send(movieTitles);
});
});
The basic thing you have to do is:
define routes which your back-end app has to respond with the spa
send your "skeleton" file to the response on that routes
Example code:
const handler = (req, res) => res.send(path.join(__dirname, "path/to/your/index.html"))
const routes = ["/", "/hello", "/world"]
routes.forEach( route => app.get(route, handler) )
This should get you started
I have 2 qeustions :
1. I want my project's url to be like 127.0.0.1:8080/param=id and I couldnt do it, I tried:
app.get('/param=id', function(req, res) {
console.log(req.param("id"));
});
if I write '/param/:id' it works but I dont want the url to look like this
I want my program to send message according to the id a json message or string to the client
So my second question is how the client gets the response - I want the message to go throgh a script in the client's side?
I would suggest using req.query instead of req.params:
app.get('/', function(req, res) {
console.log(req.query.id);
// or you may still use req.param("id")
});
requesting it like
HTTP GET 127.0.0.1:8080/?id=my_id
query is a different way of sending data to the server, designed to send key-value pairs.
Though, if id is the only thing you want to send to the server, I would recommend to stick with params, e.g.:
app.get('/:id', function(req, res) {
console.log(req.params.id);
});
requesting it like
HTTP GET 127.0.0.1:8080/my_id