I have a GET request that gets form data, then I need to trigger a second GET request on a different route that gives the form data to a REST API. I can do this manually through Postman, but I'd like the first GET request to trigger the second.
This is the idea:
app.get('form', (req,res,next) => {
//Get form data
//Pass form data
//Trigger next request
})
app.get('API', (req,res,next) => {
//Get data from previous request
//Use data in params
})
I would really appreciate any feedback! So far I've found posts talking about app._router.handle, but haven't been able to implement it correctly.
to pass data between middleware, you must assign it to request object like :
app.get('form', (req,res,next) => {
const { user, tags } = req.body
// assign this
req.data = { user, tags }
// pass to next
next()
})
app.get('API', (req,res,next) => {
// get the passed data
req.data
console.log(req.data)
})
Related
I want to update an attribute within a JSON object using fetch PUT. I've created a put function taking in 2 URL parameters
app.put('/trustRoutes/:id/:item', (req, res){
I am able to update the data with a single parameter but since I only want to change one value inside that object, calling put will replace the whole object with my new body.
below is what I've tried.
app.put('/trustRoutes/:id/:item', (req, res) => {
readFile(data => {
const userId = req.params['id/item'];
// have also tried const userId = req.params.id.item
data[userId] = req.body;
//write data back to file
I looked around at other examples but couldn't find any that were updating data instead of GET. If there is one I missed please let me know.
PUT requests are great for completely overwriting a resource, and is idempotent. This answer does a good job explaining idempotency. For updating a resource partially, a PATCH request is a better choice.
app.patch('/trustRoutes/:id/:item', (req, res) => {
readFile(data => {
data[userId] = req.params[id];
data[item] = req.params[item];
// A get request for this resource would now show both of the updated values
// Write file
I'm trying to pass a variable to EJS a second time in my code and am running into trouble. Here is my code:
axios.get(yearURL)
.then(function (res) {
let data = res.data.MRData.SeasonTable.Seasons;
years = data.map(d => d.season);
app.get('/', function (req, res) {
res.render('index.ejs', {
years: years
});
app.post('/down', function(req, res) {
let year = req.body;
res.redirect('/');
axios.get(`http://ergast.com/api/f1/${year.year}/drivers.json`)
.then(function (res) {
let data = res.data.MRData.DriverTable.Drivers;
drivers = data.map(d => `${d.givenName} ${d.familyName}`);
})
.catch(function (err) {
console.log(err);
})
res.render('index.ejs', {
drivers: drivers,
years: years
});
Whenever I run this however, I receive an error that I cannot set headers after they are sent to the client. I've also read elsewhere that apparently you can not call res.render twice. So my question is, how can I pass another set of data to EJS after I have already called res.render once before?
Here it is as pseudocode. It's good to start your program with this level of logical structure, and then implement it:
Define ready = false, errored = false, and data = undefined
variables.
Get the data from the remote API, in the then branch, set
ready = true, assign result to data. In the error branch, set errored
= true. Should we retry on error?
Define the / GET route.
If not ready, check errored. If not errored, we are still waiting for the data. In this case, do we wait for the call to resolve, or return something to the client to let them know?
If not ready, and errored, tell the client that there was an error.
If ready == true, then we have data to render a response to the client.
Define the /down route. It needs to take a year parameter, and we need to make an async call in the route handler to get the data.
Can we cache the data, so that subsequent calls for the same year return data that we fetched previously? If we can, use an object as a lookup dictionary. If the object has a key for that year, use the cached data to render the response. If not, make the call, and in the then branch, add the response to the cache object, and use the data to render the response.
I've been sitting with this for few days already and I'm brain dead from this and can't figure the best way to approach this.
What I would like to achieve is to be able to repeat the route journey with new context data on the start. So for rxample:
app.get('/test', testGet);
app.post('/test', testPost);
having those two routes I would like:
GO through testGet handler (fetch necessary data and present ui for Form)
Gather Form data and submit it for the testPost handler
Process data from form on testPost and generate appropirate new payload
Redirect again to the testGet handler with new payload data from testPost if journey not successful
How I would pass that new data to the testGet on redirection? Can't figure the best way.
Redirect doesn't accept any payload. Redirecting with query params is kinda way to go but it appends the url string with query string to the user which I would like not to be present to the user. And that data would not be a simple string but an object containing few arrays and properties
Look at this
const handleRequest = (req, res, next) => {
const view = 'myView.jsx';
let myData = {};
...do the common job
if (req.method === 'GET') {
return res.render(view, data)
}
/* here you are in the post method */
data = /* modify your data with the req.body */
return res.render(view, data)
};
app.get('/test', handleRequest);
app.post('/test', handleRequest);
I need to do some DOM manipulation based on some AJAX call. But I end up with the res.send on my page and I am unable to get the console.log I need to see the datas and be able to check what I need to insert in my Dom. All I see is the res.render and the JSON datas.
Even by trying to do some basic DOM creation it didnt work.
I manage to do some AJAX call already. Some Axios post, patch or delete, but I never needed to call the data when rendering the page, always through a button inside the page.
There must be something I am not understanding...
Router.get("/collection", async (req, res) => {
const dbRes = await Promise.all([
sneakerModel.find().populate("tag"),
tagModel.find()
]);
const sneakRes = dbRes[0];
const tagRes = dbRes[1];
res.send(tagRes);
});
// ===============================
// CLIENT SIDE =>
const allCollecRoutes = document.getElementById("allCollec");
allCollecRoutes.onclick = async () => {
const dbRes = await axios.get("http://localhost:9876/collection");
console.log(dbRes);
};
You appear to be expecting a JSON serialised response at the client but are sending a plain/text from the server i.e. res.send(tagRes)
Use res.json(tagRes) instead.
I requested stormpath user custom data by using
res.render('home', {
title: 'home',
user: req.user.customData,
});
i expected to receive a json object of custom data but instead a url ('https://api.stormpath.com/v1/accounts/WvtGbIH3kJ4rEttVF5r9U/customData') was returned. This page does have the custom data i want on it but i cannot request it using an ajax request as it is a https page. What should I do? Thanks in advance
You'll need to use the "auto expansion" feature of the library, like this:
app.use(stormpath.init(app, {
expandCustomData: true,
});
That will expand the custom data resource for you. By default it's just a link to the resource, as you've seen.
Found the best way to request custom data is to use the getCustomData() method in the route, set the data to a variable and use a get request from the client to request this data as in the sample below:
Server Js
customData = new Array;
router.get("/string", function(req, res) {
req.user.getCustomData(function(err, data) {
customData = data.someKey;
})
res.send(customData) /*Returns Empty Arrray*/
})
router.get("/cdata", function(req, res) {
res.send(customData) /*Sends Actual Custom Data*/
})
Client Js
var customData = new array
$(document).ready(function() {
$.get("/string", function(string) {
/*Tells server to get customData*/
})
$(document).click(function(){
if(pleaseCount===0){
$.get("/cdata", function(data) {
for(i=0;i<data.length;i++){
customData.unshift(data[i])
pleaseCount=pleaseCount+1
/*Custom data is now stored in client side array*/
}
})
}
})
That's what worked for me anyway. I don't know why someone down-voted the question as this is an acceptable way to retrieve other user information such as name and email by using userName:req.user.userName in the render function and rendering this information to a p. tag in a jade page by using p #{userName}