I am unable to make a POST method request with . I am unable to send a request object with it.
For example see this example. Here only GET request is being made. But I want to make a POST request.
If you want to send a POST request to an another host it would be easier to use some libraries dedicated to this task like axios or request.
I was facing the same issue. When I tried to make a POST request I was receiving undefined as the value of the body object.
I ended up not using koa-http-request as the example provided in your link. I have used both koa-bodyparser and koa-router middlewares instead:
const Koa = require('koa');
const KoaRouter = require('koa-router');
const bodyParser = require('koa-bodyparser');
const app = new Koa();
const router = new KoaRouter();
// ===== M i d d l e w a r e s =====
// Body parser
app.use(bodyParser());
// Router
app.use(router.routes()).use(router.allowedMethods());
// ...
const addItem = async (context) => {
const body = await context.request.body;
// Now you can access the body object
console.log(body)
}
// ...
router.post('/', addItem);
In my case it had worked as it supposed to. :)
Related
After watching Firebase Cloud Function Tutorial - REST API Part 1 | Diligent Dev, I have spent several hours trying to understand how to get the entire record that was posted into firestore. Here is index.js code:
const functions = require("firebase-functions");
const express = require("express");
const cors = require("cors");
const admin = require("firebase-admin");
admin.initializeApp();
const app = express();
app.use(cors({origin: true}));
app.post("/", async (req, res) => {
const user = req.body;
await admin.firestore().collection("users").add(user);
res.status(201).send(JSON.stringify(user));
});
The JSON data I posted was:
{"id":123, "name":"Tony Stark", "email":"ironMan#MarvelComics.com"}
In this get, the id is returned but I can't seem to access the other properties that are part of the record (example name: Tony Stark)?
app.get("/:id", async (req, res) => {
const snapshot = await
admin.firestore().collection("users").doc(req.params.id).get();
const userId = snapshot.id;
const userData = snapshot.data():
constole.log(userData);
res.status(200).send(JSON.stringify({id: userId, ...userData}));
});
There must be a simple solution but console.log(userData) is not the answer! :-(
Almost forgot to say, my request from the browser is passing the user id as a query parameter, in this example localhost:5001/projectReference/user/1 and I also tried with the Cloud Firestore document id (.../user/XRAwtfj9FSubeCArvUtQ). In each case I see in the browser the JSON string {"id":"the_value_requested"} but no userData.
What does console.dir(userData) output? That should help you see what's in the returned object.
Are you confident that name and email are avtually present on the record in Firebase? It's possible your retrieval is working as expected but the data expected isn't there.
I have this URL here: https://viacep.com.br/ws/01001000/json/ , that lets me retrieve JSON data whenever i change the given number on it(the number is unique). For example: 01001000 has its own data, and if i change it for 49140000, it will have its own data as well. What i want to do is: i want to save the JSON data into a database, and somehow cache/save the request, so if in the future i search for the same number again, it won't have to retrieve the data from the URL again.
I have this right now:
My city.routes.js where i make the request to the API:
const express = require('express');
const axios = require('axios');
const cityRouter = express.Router();
cityRouter.get('/:cep', async (request, response) => {
try {
const { cep } = request.params;
const resp = await axios.get(`https://viacep.com.br/ws/${cep}/json/`);
return response.json(resp.data);
} catch (error) {
return response.status(400);
}
});
module.exports = cityRouter;
An index.js to make easier to the server to import and use the routes:
const express = require('express');
const routes = express.Router();
const cityRoutes = require('./city.routes');
routes.use(cityRoutes);
module.exports = routes;
My server.js:
const express = require('express');
const routes = require('./routes');
const app = express();
app.use(express.json());
app.use(routes);
app.listen(3333, () => {
console.log('Server is on!');
});
I can retrieve the JSON data that i want without problems:
enter image description here
You can do this via using caching libraries or using db and indexing on based of number for faster retrieval.
My suggestion:
If you need to cache for smaller amount of time lets say week or so prefer caching libraries like redis or memcache.
There u can do something like:
await redis.set(key, JSON.stringify(data), { expiry: '1W'});
The above code varies depending on library you use. But the idea remains the same you cache the data with key(Number).
And next time before making request you first tries to get the key from cache provider.
await redis.get(key)
if above value is present you will get json string of the desired result and dont need to make the network call.
If not present you make the network call and cache the result for future use.
In case of DB approach you simply make a get request via key to the db.
But do index the key in collection or relation when initializing the structure for faster retrieval.
im trying to create a simple webpage with some server side functions but somehow 2 things arent working as they supposed to work.
via html button im running a clientside javascript that does a http post request.
Client side javascript
httpRequest = new XMLHttpRequest()
httpRequest.open('POST', '/test2')
httpRequest.send(var1,var2,var3,var4);
Server.js
var express = require('express');
var bodyParser = require("body-parser");
var dbFunc = require("./dbFunctions.js");
var app = express();
var path = require('path');
var port = 8888;
//allow to use body-parser
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//allow to use static files
app.use(express.static("public"));
//listen to smth
app.post('/test2', function (req, res) {
console.log("worked");
});
//start server
app.listen(port);
console.log("Server running on port" + port);
My server detects this post http request and does the "console.log" but how do i get the parameters from the http.request as a variable? I tried to work with bodyParser but somehow my object is always empty.
Another thing is, ive created another Javascript file(dbFunctions.js) and also implemented it in the server file but if i try to run a function(dbFunc.test("hello") for example) it says "dbFunc.test is not a function".
dbFunctions.js
function DBFunctions(){
function test(a){
console.log(a);
}
}
Ive also tried to do something like this, but this gave me the same error.
function test(a){
console.log(a);
}
Could someone give me a hint or tell me what i am missing?
Answer1:
The way you are sending data into post request is wrong, you slould send in format of,
xhttp.send("val1=val1&val2=val2");
httpRequest = new XMLHttpRequest()
httpRequest.open('POST', '/test2')
httpRequest.send(var1=var1&var2=var2&var3=var2&var3=var3);
To POST data like an HTML form, add an HTTP header with setRequestHeader(). Specify the data you want to send in the send() method:
httpRequest = new XMLHttpRequest()
httpRequest.open('POST', '/test2')
httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
httpRequest.send(var1=var1&var2=var2&var3=var2&var3=var3);
In your server.js, use req.body to get those values.
app.post('/test2', function (req, res) {
console.log("worked");
console.log(req.body)
});
XMLHttp request example
Answer2:
From your dbFunctions.js file you should export your function using module exports in node js.
dbFunctions.js:
var exports = module.exports = {};
exports.test = function(a) {
console.log(a);
};
You can also do as,
module.exports = {
test: function(a) {
console.log(a)
},
}
Now in your server.js
var dbFunc = require("./dbFunctions.js");
dbFunc.test();
Node js module exports
All your posted variables will be available in req.body try console.log(req.body).
Secondly you most probably not exporting test function from dbFunction.js, that's why getting "dbFunc.test is not a function" because dbFunc.test is undefined.
Note: As mentioned in one of the comment, you need to use httpRequest.send(var1,var2,var3,var4); in the right way. It does not expect multiple parameters.
Like: httpRequest.send("var=var1&var1=var2")
Please refer: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
So the client makes a get request using a button on the index page. This sends some information to a route which has been set up as follows:
app.js
var route = require('./routes/index');
var button = require('./routes/button');
app.use('/', index);
app.use('/button', button);
The request is sent from a client-side directory to the node framework whenever someone presses the button. If the request is sent to 'localhost:port/button', then the button.js file mentioned above will receive the request. So in the button.js file we have something like the following:
var express = require('express');
var router = express.Router();
var someData = '';
router.get('/', function (req, res, next) {
//make a get request here such that someData
//receives whatever the request returns from another
//set up framework(i.e. Spring...)
someData = getRequest('some other URL');
res.send(someData);
};
module.exports = router;
The problem here is that the getRequest('some other URL') within the router get request never receives any information.
Also (as a side-note), I cannot seem to find in the express API as to why we have
router.get('/')...
instead of
router.get('/button')...
to access and make requests to the button page.
Any help would be very much appreciated!
You want to make a request to some other REST API running somewhere else right?
You can use node-rest-client for that.
I guess you are confusing what is server code and client code or do I´m missing something?
I´ll try to explain the way it works:
Server code:
var express = require('express');
var router = express.Router();
var someData = '';
router.get('/yearStations/:id', function (req, res, next) {
//make a get request here such that someData
//receives whatever -the id parameter- the request returns from another
//This is express.js
someData = getYourDataFromDataBase(req.params.id);
res.send(someData);
};
module.exports = router;
Client code:
JS (angular.js)
$scope.getInfo = function() { //here you make the GET call to the server
$http.get("http://localhost:XXXX/yearStations/Spring").then(
function(success){
alert(success.data);//this should be your data
});
};
HTML
<button ng-click="getInfo()">getInfo</button>
I'm trying to get back from the remote site(URL) in the following node.js codes.
Case 1: Using basic HTTP module + request module
var http = require('http');
var fs = require('fs');
var request = require('request');
var server = http.createServer(function(req, res) {
// Can't get back any response from remote URL
// Can't use 'res' or nothing have in res
request('http://remote.foo.com/app/lists/dosomething.json',
function(err, response, body) {
console.log(body);
}
);
var host = 'http://remote.foo.com';
var app = '/app/lists/dosomething.json?';
var url = 'param1=a¶m2=b';
// I can get something to print out back
request.get(host+app+url).pipe(res);
});`
Case 2: Using Express + request module
var express = require('express')
, http = require('http')
, path = require('path')
, net = require('net')
, url = require('url')
, qs = require('qs');
var request = require('request');
//.....
app.get('/test/foo.json', function(req, res) {
var url_parts = url.parse(req.url, true);
var query = qs.parse(url_parts.query);
var host = 'http://remote.foo.com';
var app = '/path/dosomething.json?';
var url = 'param1=a¶m2=b';
//the following line, the same code above Case 1
//can't get any result, just blank..
request.get(host+app+url).pipe(res);
res.end();
});
//....
Can anyone explain it?
Thanks
Expanding on my comment a little bit:
When you pipe() a readable stream into a writable stream, by default writable.end() is called when the readable stream emits the end event (see documentation). This means that when you pipe streams, you don't have to explicitly close the destination stream by yourself: it is automatically closed when the source closes. This should make sense: when the source stream ends, the destination stream doesn't have anything to do, and should indeed close.
In your second example, you first pipe a readable stream (request) into a writable stream (res), but the very next instruction closes the res stream, without even reading anything, since the first read() call is executed on the next tick (see source). The solution is then to remove res.end(), since it will be handled automatically.
As a side note: if you need to keep the destination stream open for some reason, you can pass {end: false} to pipe.