How to send request from Express server to another server? - javascript

I am trying to fetch data from Express server from another external server.
That is search api, which is post request and I am from client get body params.
Then try to send that params on another server:
http://search-api.com/d/explore?
public static async search(req: Express.Request, res: Express.Response) {
try {
const data = await axios.post(
`http://search-api.com/d/explore?user_id=${
req.body.id
}`,
{
query: req.body.query,
topics: req.body.topics
}
);
res.send(data);
} catch (err) {
ErrorHandler.handle('Error fetching search response.', err, res);
}
}
This is response Error:
[ERROR] default - "Error fetching search response."
Error: Request failed with status code 422
I was check params exist and they are ok.
Does anyone have idea what can be the problem here?
UPDATED:
This is how body of request should looks:

Probably you have forgot about http:// protocol on beginning; also, you have wwww instead of www, but I assume that it's just dummy text there:
public static async search(req: Express.Request, res: Express.Response) {
try {
const data = await axios.post(
`http://www.search-api.com/d/explore?user_id=${
req.body.id
}`,
{
query: req.body.query,
topics: req.body.topics
}
);
res.send(data);
} catch (err) {
ErrorHandler.handle('Error fetching search response.', err, res);
}
}

Related

Data not getting inserted into database, despite of 201 request status - postgresql express js

I am using Typescript, Express, PostgresDB.
Here is my code for connecting to the database cluster.
import { Pool } from "pg";
const myPool = new Pool({
host: `${process.env.DATABASE_URL}`, //somedb.abc.us-east-1.rds.amazonaws.com
database: `${process.env.DATABASE_NAME}`, //dbName
user: `${process.env.DATABASE_USER}`, //dbUser
password: `${process.env.DATABASE_PASSWORD}`, //dbPassword
port: 5432
});
myPool.connect();
Here is my post route:
const router = express.Router();
router.post("/item/new", async (request, response) =>{
try{
const { itemTitle } = request.body;
const myItem = await myPool.query(`INSERT INTO items VALUES('${itemTitle}')`), (resp, err) =>{
if(err){
return err;
}
return resp;
});
return response.status(201).json({message: myItem});
}catch(err){
return response.status(400).json({message: `${err}`});
}
});
When I send the request, I get the following response with a 201 status code, but nothing
is inserted into the database:
{
"message": {}
}
It's because you're sending the callback function with the wrong argument's order. The first argument for the callback is error, not result.
It should be like this:
client.query('SELECT NOW() as now', (error, result) => {
if (error) {
console.log(error.stack)
} else {
console.log(result.rows[0])
}
})
documentation.
You can try to print the query that you are passing to find the error.
The reason is that you are concatenating a json object with string which is wrong, instead try this:
`INSERT INTO items(col1, col2) VALUES(${itemTitle.col1}, ${itemTitle.col2})`

How to make a POST request from Flutter to Amplify REST API

Following the getting started documentation for Amplify Flutter REST API, the auto-generated POST request below for ExpressJS results in the following error:
SyntaxError: Unexpected token ' in JSON at position 1
at JSON.parse
The GET request returns fine, but when changing to POST and adding the body field below from the documentation the error is returned. How can a POST request be successfully called from Flutter using the Amplify REST API?
Flutter GET Request - (no error)
Future<void> callAPI() async {
try {
RestOptions options = RestOptions(
path: '/example',
apiName: 'ExpressJSRESTAPI'
);
RestOperation restOperation = Amplify.API.get(
restOptions: options
);
RestResponse response = await restOperation.response;
print('GET call succeeded');
print(new String.fromCharCodes(response.data));
} on ApiException catch (e) {
print('GET call failed: $e');
}
}
Flutter POST Request (throws error)
Future<void> callAPI() async {
try {
RestOptions options = RestOptions(
path: '/example',
body: Uint8List.fromList('{\'name\':\'Mow the lawn\'}'.codeUnits),
apiName: 'ExpressJSRESTAPI'
);
RestOperation restOperation = Amplify.API.post(
restOptions: options
);
RestResponse response = await restOperation.response;
print('POST call succeeded');
print(new String.fromCharCodes(response.data));
} on ApiException catch (e) {
print('POST call failed: $e');
}
}
ExpressJS GET request path
app.get('/example', function(req, res) {
// Add your code here
res.json({success: 'get call succeed!', url: req.url});
});
ExpressJS POST request path
app.post('/example', function(req, res) {
// Add your code here
res.json({success: 'post call succeed!', url: req.url, body: req.body})
});
From the documentation, notice the reverse slash (\) in your RestOptions' fromList arguments.
RestOptions options = RestOptions(
path: '/todo',
body: Uint8List.fromList('{\'name\':\'Mow the lawn\'}'.codeUnits)
);
Based on the github discussion here the issue happening due to unneeded escape character.
Change your body parameter to this:
body: Uint8List.fromList('{"name":"Mow the lawn now!"}'.codeUnits)
or
body: ascii.encode('{"name":"Mow the lawn"}')

401 Error when sending axios get request with Auth Headers

In my react project, I have been using axios to help get data from MongoDB.
My axios get requests return a 401 error when I add my auth middleware as a param. This middleware requires the user to have a valid JWT token before any data is returned.
When making the request with Insomnia/Postman, as long as long as the user token is added to the request headers, I always get the desired data returned. However, when I try to get the data within the react application, I get a "Failed to load resource: the server responded with a status of 401 (Unauthorized)" error log, along with my custom json error response, "No Auth token, authorisation denied!"
I built a simple boolean function that returns true if the current user has a valid JWT token. Despite returning true, I am still receiving the 401 error as a response, which leads me to suspect there is a syntax or formatting error somewhere inside my react code.
Backend (with express):
router.get("/allauth", auth, async (req, res) => {
const players = await Player.find();
res.json(players);
});
Auth:
const jwt = require("jsonwebtoken");
const auth = (req, res, next) => {
try {
const token = req.header("x-auth-token");
if (!token)
return res.status(401)
.json({ msg: "No Auth token, authorisation denied!" });
//match token against .env password
const verified = jwt.verify(token, process.env.JWT_SECRET);
if (!verified)
return res.status(401)
.json({ msg: "Token verification failed, authorisation denied!" });
req.user = verified.id;
next();
} catch (err) {
res.status(500).json({ error: err.message });
}
};
React frontend:
export default function DisplayTeam() {
const [players, setPlayers] = useState([]);
const {userData} = useContext(UserContext);
useEffect(() => {
let token = localStorage.getItem("auth-token");
const url = "http://localhost:5000/players";
console.log(token);
axios.get(`${url}/allauth`, {
headers: {
"Authorization": `x-auth-token ${token}`
}
})
.then( response => setPlayers(response.data))
.catch( error => console.log(error));
}, []);
return (//display from DB);
Based on your server config, you need to pass X-Auth-Token header not Authorization,
it should be:
headers: {
"X-Auth-Token": token
}
Also, Take into consideration that headers are Case Sensitive!

Axios and Express: Sending params in Get request sends an empty params object to the backend

Here's the Axios request:
API.get("api/client/getClientByPK", { params: { id: 22 } });
Here's the Express router:
router.get("/getClientByPK", function(req, res) {
logger.info("req.params", JSON.stringify(req.params));
clientServices.getClientByPK(req.params.id, res);
});
getClientByPk
var getClientByPK = function(clientPk, res) {
models.client
.findByPk(clientPk)
.then(clientFound => {
logger.debug("clientPk", clientPk);
logger.info("clientFound", JSON.stringify(clientFound));
if (clientFound != null) {
res.status(200).json(clientFound);
} else {
res.status(404).json({ error: "ClientNotFound" });
}
})
.catch(error => {
logger.error(error);
res.status(400).json(error);
});
};
This is the log result:
2020-03-16T15:31:10+0100 <info> client_routes.js:12 req.params + {}
2020-03-16T15:31:10+0100 <debug> ClientServices.js:21 clientPk +
2020-03-16T15:31:10+0100 <info> ClientServices.js:22 clientFound + null
I have tested the Backend with POSTMAN, and it works perfectly. So I believe the problem lies in the AXIOS request.
PS: I've found only one answer on SO suggesting that I use data instead of params but it's still the same result.
Axios sends the params object as query parameters.
You should access the query parameters in express through req.query not req.params

Database is updated sucessfully, but API returns 500 error

I am currently working on a project that is using Javascript with Node.js, Express, SuperAgent and KnexJS (database framework for Sqlite3). My problem is this:
When I submit data for updates via my API route using the PUT method, my database is updating successfully, but my console returns this error:
PUT http://localhost:3000/user/contracts/ 500 (unknown)
Error: unknown
at Request.<anonymous> (client.js:423)
at Request.Emitter.emit (index.js:133)
at XMLHttpRequest.xhr.onreadystatechange (client.js:735)
Here is some snippets of my API, Routes, and DB code.
api.js
const request = require('superagent')
const updateUserContract = (callback, id, contractData) => {
request
.put('http://localhost:3000/user/contracts/' + id)
.set('Content-Type', 'application/json')
.send(contractData)
.end(function (err, res) {
if (err) {
callback(err)
} else {
callback(null, "Status: 200")
}
})
}
module.exports = { updateUserContract }
routes.js
router.put('/contracts/:id', function (req, res) {
var id = req.params.id
var signatureUrl = req.body.signature_url
db.signContract(id, signatureUrl).then((result) => {
res.sendStatus(result)
})
.catch((err) => {
res.status(500).send(err)
})
})
db.js
function signContract (id, signatureUrl) {
return knex('contracts').where('id', id)
.update({ signature_url: signatureUrl }).into('contracts')
}
Was answered by #Sombriks. "about your error, you're sending sql status as if it where an http status. my best guess is, it's being "promoted" to an error 500. try simply req.send("OK"), it will deliver status 200 as default".

Categories

Resources