I wrote a function that receives my list from the server (NODEJS) in the REACT language
getList = () => {
const request = new Request('http://localhost:3000/api/get');
fetch(request, {method: 'GET',mode: 'no-cors',
})
.then((response) => console.log("response", response.JSON()));
}
The request is being made but the returned value I receive in CONSOLE.LOG is:
response Response {type: "opaque", url: "", redirected: false, status: 0, ok:
false, …}body: (...)bodyUsed: falseheaders: Headers {}ok: falseredirected: falsestatus:
0statusText: ""type: "opaque"url: ""__proto__: Response
This is the code on the server:
const MyList=[
{id:1,name:'to do list'},
{id:2,name:'to sleep'},
]
app.get('/api/get',(req,res)=>{
res.send(MyList);
});
Where is the values of the list returned from the server ???
The data from the server can be accessible from response.body, however response.json() returns a promise, so you will have to do something like this:
getList = () => {
const request = new Request('http://localhost:3000/api/get');
fetch(request, {method: 'GET',mode: 'no-cors'})
.then((response) => response.json().then(json => {
console.log(json.body);
});
}
I added .json to response:
getList = () => {
const request = new Request('http://localhost:3000/api/get');
fetch(request, {method: 'GET',mode: 'no-cors' })
.then((response) => console.log("response", response.json()));
}
and received the following error:
TobuyList.js:30 Uncaught (in promise) SyntaxError: Unexpected end of input
at TobuyList.js:30
In your server, change res.send to res.json
On the client side (taken from mozilla docs):
fetch('http://localhost:3000/api/get', { mode: 'no-cors' })
.then(response => response.json())
.then(data => console.log(data));
Related
I'm using ReactJS to run my front-end and using Express for my back-end. I want to make a get request to my back-end using the "/paas" path to get a listing of all of my pods that are running inside my namespace in Rancher(Kubernetes).
The back-end then needs to be able to make an https request to my Rancher API endpoint and return the result to the front-end. I can make the successful call to Rancher API and see the data print to the screen on my back-end but I get lost when trying to send this data to the front-end and console log it out inside the browser.
Due to "pre-flight" errors, I can't just make a direct call to the Rancher endpoint inside of my App.js file. More info on this here. So I need to go the custom back-end route. I any case, it seems like this should be pretty straightforward. Any guidance would be appreciated.
App.js:
import React, { useEffect } from "react"
import axios from "axios"
function App() {
useEffect(() => {
const fecthPods = async () => {
try {
const response = await axios.get(`http://localhost:3001/paas`)
console.log(response.data)
} catch (err) {
if (err.response) {
// Not in the 200 response range
console.log(err.response.data)
console.log(err.response.status)
console.log(err.response.headers)
} else {
console.log(`Error: ${err.message}`)
}
}
}
fecthPods()
},[])
return (
<div>
Hello World!
</div>
);
}
export default App;
Back-end server.js:
import express from "express"
import cors from "cors"
import https from "https"
import bodyParser from "body-parser";
const app = express()
app.use(cors())
app.use("/data", (req, res) => {
res.json({ name: "Minion", favFood: "pizza"})
})
app.get("/paas", bodyParser.json(), (req, res) => {
const options = {
hostname: "k8.fqdn.com",
port: 443,
path: "/k8s/clusters/c-wwfc/v1/pods/mynamespace",
method: "GET",
headers: {
Authorization: "Bearer token:12345"
}
}
const request = https.get(options, (res) => {
let responseBody = ""
res.setEncoding("UTF-8")
res.on("data", (chunk) => {
console.log("---chunk", chunk.length);
responseBody += chunk;
});
res.on("end", () => {
let json = JSON.parse(responseBody)
// console.log(responseBody)
console.log("Response finished");
res.json({data: responseBody})
});
});
request.end()
res.json({ status: "complete", data: request.data})
})
app.listen(3001)
console.log("backend up on 3001")
I see a couple of errors on your backend code.
First, you are naming the res variable for the express middleware and also for the response received by the https module. In this way, you lose the possibility to access to the express response object in the on.('end') callback.
Secondly, you are triyng to respond to the client multiple times (inside the on.('end') callback and also directly inside the express middleware with the instruction res.json({ status: "complete", data: request.data}). Also, consider that the code you wrote is repliyng to the client before the call to the k8s cluster is made. And the response will always be a JSON with this data: { "status": "complete", "data": undefined}.
To fix all, try with this code (I will try to comment all edits):
app.get("/paas", bodyParser.json(), (req, res) => {
const options = {
hostname: "k8.fqdn.com",
port: 443,
path: "/k8s/clusters/c-wwfc/v1/pods/mynamespace",
method: "GET",
headers: {
Authorization: "Bearer token:12345"
}
}
const k8sRequest = https.get(options, (k8sResponse ) => { // as you can see I renamed request and res to k8sRequest and k8sResponse, to avoid loosing the scope on req and res express middleware variables
let responseBody = ""
res.setEncoding("UTF-8")
k8sResponse.on("data", (chunk) => { // here use k8sResponse to collect chunks
console.log("---chunk", chunk.length);
responseBody += chunk;
});
k8sResponse.on("end", () => { // here use k8sResponse again
let json = JSON.parse(responseBody)
// console.log(responseBody)
console.log("Response finished");
res.json({ status: "complete", data: responseBody}) // here use the express res variable, to reply to the client.
});
});
k8sRequest.end() // here use the k8sRequest variable to make the https call to the k8s cluster
// here I deleted the res.json instruction
})
The above code should just works. Anyway, I suggest you using axios also with your backend service. You are already using it with React, so you know how to use it. The syntax is minimal and easier and you can use the async/await approach.
Axios solution:
import axios from "axios"
app.get("/paas", bodyParser.json(), async (req, res) => {
try {
const url = 'https://k8.fqdn.com/k8s/clusters/c-wwfc/v1/pods/mynamespace'
const k8sResponse = await axios.get(url, headers: {
Authorization: "Bearer token:12345"
})
res.json({ status: "complete", data: k8sResponse.data })
} catch (e) {
res.json({status: "error", data: e.response.data})
}
})
You should wrap your axios call inside a try/catch block to properly handle errors like you are doing with your React implementation. Error handling should be also implemented if you still want you the native node.js https module
I am invoking a web service through an azure function in node.js with Axios, I have a couple of questions here.
1- in the body of this request I'm hardcoding the value for appUser. however, if I want to run this request on postman and pass the JSON value in the body for appUserwhat changes do I need to do in the code so the param value can pick up what is being passed.
2- the response for this request is only returned in the console of the editor but not getting sent to the client response body (i.e. postman) any idea how to forward the response?
module.exports = async function () {
const axios = require("axios");
const data = {
appUser: "yamen",
};
const headers = {
Authorization:
"Basic WUFNkVQRDg9",
};
{
axios
.post(
"https://tegossl/GetAppUser?company=Enva",
data,
{ headers: headers }
)
.then((response) => {
console.log(`Status: ${response.status}`);
console.log("data: ", response.data);
})
.catch((err) => {
console.error(err);
});
}
};
I have an Angular Universal app. I am trying to access an external API, but doing it directly through the HttpClient generates a Cors error. In development, I successfully used a proxy to make the call. I am trying to implement a proxy in production by creating a route on my express server that will swap in the appropriate external API route. I am having trouble seeing anything online that can help with this particular situation. I seem to have set up the route ok. I'm getting a 200 ok error but no data is being sent. Can anyone help?
server.ts
app.route('/api/book').get((req, res) => {
https.get('https://api2.isbndb.com/book/' + req, (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
res.send(res.json(data)
);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
});
You can simply enable cors from your server side like this.
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
For better understanding or to configure cors() url through.
can see here.
As by default it will call the options method to check the permission for the user to access that end points.
or you can use below example from client side api call,
let data = { name: 'Peter Parker', age: 34 };
const results = await fetch(
'http://localhost:3000/api/v1/results',
{
method: "post",
mode: "cors",
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify(data)
}
)
.then(res => res.json())
.then(res => {
return res;
})
.catch(error => {
error.response = {
status: 0,
statusText:
"Cannot connect. Please make sure you are connected to internet."
};
throw error;
});
i'm gonna test REST API using Cypress.io , but using chaining request, it wants to be work like this, JSON response body on the first API will be used on the next API Headers for Authorization
I'm already try doing by using cypress commands and printing on console.log, but seems like it does not captured on the log, or is there any clue for this, or i just using another command like cy.route ?
Cypress.Commands.add("session", () => {
return cy.request({
method: 'POST',
url: '/auth/',
headers: {
'Content-Type': 'application/json',
},
body: {
"client_secret" : ""+config.clientSecret_staging,
"username": ""+config.email_staging,
"password": ""+config.password_staging
}
}).then(response => {
const target = (response.body)
})
})
it('GET /capture', () => {
cy.session().then(abc =>{
cy.request({
method: 'GET',
url: '/capture/'+target
})
})
})
the goal is to capture parse of JSON array from target = (response.body)
You have two options:
leave the code as is, be aware that the
.then(response => {
const target = (response.body)
})
code isn't returning anything so the cy.session().then(abc =>{ ... code is getting the whole response (abc is the response of the first .then)
change the code into
.then(response => {
const target = (response.body)
return target // I added this return
})
and then your abc param will be equal to response.body and not to response
That's because if you don't return a subject from your chainable calls the default one will be passed to the next .then function.
Let me know if it satisfies your issue.
p.s. Welcome 👋
I have a working image-upload front/back-end code working. Now I would like to be able to GET the image from server after it is uploaded.
The problem is that the images must be behind an authenticated route, where user has to pass jwt token in header or body.
When i try to fetch the image like this:
fetch(imageURL, {
method: 'GET',
headers: {
'x-access-token': localStorage.getItem('token')
}
I just get a Form object as the response:
<img alt="Your pic" src="[object FormData]">
Would there be some way to get the image into HTML 'img' tag other than just pasting the url in 'src' attribute, since it leads to 401 (Unauthorized)
You can try the following snippet:
const myImage = document.querySelector('img');
// I make a wrapper snippet which will resolve to a objectURL
function fetchImage(url, headers) {
return new Promise((resolve, reject) => {
fetch(url, headers)
.then(response => response.blob()) // sending the blob response to the next then
.then(blob => {
const objectUrl = URL.createObjectURL(blob);
resolve(objectUrl);
}) // resolved the promise with the objectUrl
.catch(err => reject(err)); // if there are any errors reject them
});
}
fetchImage(imageUrl, {
method: 'GET',
headers: {
'x-access-token': localStorage.getItem('token')
}
})
.then(objectUrl => myImage.src = objectUrl)
.catch(err => console.log(err));
An other example for you to try you can find at:
https://davidwalsh.name/convert-image-data-uri-javascript