Axios and expressJs request debugging for external HTTP request - javascript

My use case or problem arising might be simple. I am not able to debug or figure out why my request is logging Pending promise. Let me kick in all relevant code and we can talk then
index.html
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Infinite Scroll</title>
<script src="./infiniteScroll.js" defer></script>
</head>
<body>
<div id="testimonial-container"></div>
</body>
</html>
infiniteScroll.js
async function fetchAndAppendTestimonials(limit = 5, after = 0) {
const testimonialsResponse = await fetch('/testimonials');
const testimonials = testimonialsResponse.json();
console.log(testimonials);
}
fetchAndAppendTestimonials(5, 0);
I starting adding server.js incrementally so that I can bypass CORS to call the external API - 'https://api.frontendexpert.io/api/fe/testimonials';
server.js
const express = require('express');
const cors = require('cors');
const path = require('path');
const axios = require('axios');
const app = express();
const port = process.env.PORT || 80;
app.use(cors());
app.use(express.static('public'));
const API_BASE_URL = 'https://api.frontendexpert.io/api/fe/testimonials';
async function fetchTestimonials(limit = 5, after = 0) {
const testimonialUrl = new URL(API_BASE_URL);
testimonialUrl.searchParams.set('limit', limit);
testimonialUrl.searchParams.set('after', after);
try {
const testimonials = await axios.get(API_BASE_URL);
return testimonials.data;
} catch (error) {
console.log(error);
return error;
}
}
app.get('/testimonials', function (req, res) {
const testimonials = fetchTestimonials(5, 0);
console.log('testimonials', testimonials);
res.json(testimonials);
});
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, '/index.html'));
});
app.listen(port, function () {
console.log('Server is running on port', port);
});
This is the entire app (w/o package.json and other meta files) so far and what I don't understand is that inside server.js file and fetchTestimonials function, the testimonials returned are Promise { <pending> }. This is evident from the console.log I have after the function call.
Can anyone correct this so that I can return a JSON response back to my client side infiniteScroll.js file?
Tangential but if someone, could add if this is the best approach to allow CORS would be great.

You don't seem to be awaiting fetchTestimonials inside your /testimonials route. By making your route handler async, you can solve the Promise {<pending>}
app.get('/testimonials', async function (req, res) {
try {
const testimonials = await fetchTestimonials(5, 0);
console.log('testimonials', testimonials);
res.json(testimonials);
} catch (error) {
console.log(error);
res.status(500).json({ error: 'Internal Server Error' });
}
});

Related

Not able to resolve the Promise on client side JS form express res.json

I am not able to debug or figure out why my request is logging raw HTTP response as shown in the image on the browser console once the expressjs server returns the JSON response. Let me kick in all relevant code and we can talk then
index.html
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Infinite Scroll</title>
<script src="./infiniteScroll.js" defer></script>
</head>
<body>
<div id="testimonial-container"></div>
</body>
</html>
infiniteScroll.js
async function fetchAndAppendTestimonials(limit = 5, after = 0) {
const testimonials = await fetch('/testimonials');
console.log(testimonials);
}
fetchAndAppendTestimonials(5, 0);
I starting adding server.js incrementally so that I can bypass CORS to call the external API - 'https://api.frontendexpert.io/api/fe/testimonials';
server.js
const express = require('express');
const cors = require('cors');
const path = require('path');
const axios = require('axios');
const app = express();
const port = process.env.PORT || 80;
app.use(cors());
app.use(express.static('public'));
const API_BASE_URL = 'https://api.frontendexpert.io/api/fe/testimonials';
async function fetchTestimonials(limit = 5, after = 0) {
const testimonialUrl = new URL(API_BASE_URL);
testimonialUrl.searchParams.set('limit', limit);
// testimonialUrl.searchParams.set('after', after);
try {
const testimonials = await axios.get(testimonialUrl);
// console.log(testimonials);
return testimonials.data;
} catch (error) {
console.log(error);
return error;
}
}
app.get('/testimonials', async function (req, res) {
const testimonials = await fetchTestimonials(5, 10);
console.log(testimonials);
res.json(testimonials);
});
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, '/index.html'));
});
app.listen(port, function () {
console.log('Server is running on port', port);
});
So on the client console, I am getting a log of raw HTTP response and not the actual JSON. On the express server function, I am getting the exact response. Don't know what is missing.
const testimonials = await fetch('/testimonials');
console.log(testimonials);
I am not able to debug or figure out why my request is logging raw HTTP response
Well, the first step would be to read the documentation for fetch:
Return value: A Promise that resolves to a Response object.
fetch returns a Response object wrapped in a promise.
You're unwrapping it with await and then logging the Response object.
It has various methods on it (such as the json method to wait for the body data to arrive and process it in various ways.
For example, if you want to get the JSON representation of the response body, you can do the following:
const response = await fetch('/testimonials');
const testimonials = await response.json()
console.log(testimonials);

How can I send a POST request to display a message to an html file using axios?

I'm using the weatherstack API and want to send the current temperature of a given city to a simple form in html using the POST method in express (or axios, if possible).
I tried to use the GET method in axios to consume the API and the POST method in express to send the result once the user enters the city they want in the search bar. The code is the following:
app.js
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const axios = require('axios');
const access_key = '...'
app.use(bodyParser.urlencoded({extended: false}));
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
// Successful GET in the console
// axios.get(`http://api.weatherstack.com/current?access_key=${access_key}&query=Dallas`)
// .then(response => {
// const apiResponse = response.data;
// console.log(`Current temperature in ${apiResponse.location.name} is ${apiResponse.current.temperature}℃`);
// }).catch(error => {
// console.log(error);
// });
// ----The problem-------
app.post('/', async function (req, res) {
const{response} = await axios(`http://api.weatherstack.com/current?access_key=${access_key}&query=${req.body.cityName}`)
res.send(`<p>Current temperature in ${req.body.cityName} is ${response.current.temperature} ℃</p>
<a href = '/'>Back</a>`)
});
//------------------------
app.listen({port: 4000}, () => {
console.log("Server running on localhost:4000");
});
The website
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weatherstack</title>
</head>
<body>
<form action="/" method="post">
<p>Inform the city</p>
<input name="cityName">
<button type="submit">Send</button>
</form>
</body>
</html>
But when I run the server I get this error:
How can I solve that?
Axios return the AxiosResponse object.
export interface AxiosResponse<T = any, D = any> {
data: T;
status: number;
statusText: string;
headers: RawAxiosResponseHeaders | AxiosResponseHeaders;
config: AxiosRequestConfig<D>;
request?: any;
}
the content of your response is within the data object.
const { data } = await axios(
`http://api.weatherstack.com/current?access_key=${access_key}&query=${req.body.cityName}`
);
res.send(
`<p>Current temperature in ${req.body.cityName} is ${data.current.temperature} ℃</p><a href = '/'>Back</a>`
)
Or
const response = await axios(
`http://api.weatherstack.com/current?access_key=${access_key}&query=${req.body.cityName}`
);
res.send(
`<p>Current temperature in ${req.body.cityName} is ${response.data.current.temperature} ℃</p><a href = '/'>Back</a>`
)
I tested this code, and it works fine.

How to send data from Node js server to client side?

I currently set up a node server which gets some data submitted from a html page and uses it to fetch data from an API. now I would like to display this data in a graphic format to a new html page (or even the same if possible).
In order to do this I think I should first send the data to the client side js. So that it gets the data to create the graph onto the new html page. But how would I do this? I tried to look for some examples unsuccessfully.
Here's a failing attempt at this (I omitted some code that I think wasn't influencial):
//server (Node JS)
const app = express();
app.use(express.json());
app.use(express.urlencoded( {extended: true} ));
const port = process.env.PORT || 8080;
let values;
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, '/index.html'));
});
async function fillArrays (from, to) {
...
}
const fetchData = async () => {
...
values = ...;
}
app.post('/input', async function(req,res){
await fillArrays(req.body.a, req.body.b);
console.log("End");
res.sendFile(path.join(__dirname, '/graph.html'));
res.json(await fetchData());
});
app.listen(port);
console.log('Server started at http://localhost:' + port);
graph.html:
<head>
<script src='https://cdn.plot.ly/plotly-2.14.0.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js'></script>
<script type="text/javascript" src="chart.js"></script>
</head>
<body>
<div id='myDiv'></div>
</body>
chart.js :
let dataset;
//attempt at getting data from server side
const promise = fetch('/input');
promise.then(response => {
if(!response.ok){
console.error(response)
} else {
return console.log(response);
}
}).then(result => {
dataset = result;
})
let range1 = Math.min(dataset[0]);
let range2 = Math.max(dataset[0]);
var trace = {
...
}
var data = trace;
var layout = {
...
};
Plotly.newPlot('myDiv', data, layout);

How can I preview a PDF on the front end using it's data sent from the back-end with Expressjs?

I sent a PDF stored on my back-end using Expressjs.
// FILE: app.js
const express = require('express');
const app = express();
var fs = require('fs');
app.use(express.static('./methods-public'));
app.get('/api/pdf', (req, res, next) => {
const path = './dog.pdf';
if (fs.existsSync(path)) {
res.contentType('application/pdf');
fs.createReadStream(path).pipe(res);
} else {
res.status(500);
console.log('File not found');
res.send('File not found');
}
});
app.listen(5000, () => {
console.log('Server is listening on port 5000....');
});
My front-end received the raw data using Javascript with Axios.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<div class="result"></div>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"
integrity="sha512-bZS47S7sPOxkjU/4Bt0zrhEtWx0y0CRkhEp8IckzK+ltifIIE9EMIMTuT/mEzoIMewUINruDBIR/jJnbguonqQ=="
crossorigin="anonymous"
></script>
<script>
const result = document.querySelector('.result');
const fetchPDF = async () => {
try {
const { data } = await axios.get('/api/pdf');
result.innerHTML = '<h3>' + data + '</h3>';
} catch (error) {
result.innerHTML = `<div class="alert alert-danger">Can't Fetch PDF</div>`;
}
};
fetchPDF();
</script>
</body>
</html>
My front end-knowledge is very limited. I've been struggling to understand how I can use this data to render the pdf then display it within a Canvas.

Node.js Express.js Send Jquery Ajax Post throws Constant Error - I'm stuck

I'm trying to make a very simple return coming from Node.js to Ajax. I'm using Express.js to make this possible.
I have code from the previous route that I did in order to write and manage JSON files and it works just fine.
The problem comes from the second route that always throws an error when I'm trying to make it return something with the JQuery ajax success method. It is the most simple form of send that I found but still doesn't work.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test 2</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
</head>
<body>
Cod: <input type="text" name="cod" id="cod">
Text: <input type="text" name="text" id="text">
<button id="boton">PRUEBA</button>
<button id="getText">GET TEXT</button>
<script>
$('#boton').click(function() {
let cod=$('#cod').val();
let text=$('#text').val();
console.log(cod);
console.log(text);
$.ajax({
type: 'POST',
data: {
cod: cod,
text: text,
},
url: 'http://localhost:1337/prueba'
});
});
$('#getText').click(function() {
$.ajax({
type: 'POST',
data: {
},
success: (result) => {
console.log(result);
},
error: (result) => {
console.log('ERROR');
},
url: 'http://localhost:1337/getText'
});
});
</script>
</body>
</html>
app.js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/prueba', function(req, res) {
// ... First Route. The code here works just fine so I don't add it here.
});
app.post('/getText', function(req, res) {
let text = "Hola mundo";
console.log(text);
res.send(text);
});
app.listen(1337, () => console.log('Started server at http://localhost:1337!'));
When you click the 'GET TEXT' Button it enters inside the '/getText' route in app.js and console.logs the text on the node.js terminal so that's not the issue.
The issue seems to come from the res.send() function.
In the browser console it logs 'ERROR' as it appears in the ajax error method associated to the 'GET TEXT' Button. I can't find a way to make it return success.
Could anyone help me? I'm so stuck with this project for work.
looks like a CORS issue... do you serve index.html from the same location?
It works serving index.html from node
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/prueba', function(req, res) {
// ... First Route. The code here works just fine so I don't add it here.
});
app.post('/getText', function(req, res) {
let text = "Hola mundo";
console.log(text);
res.send(text);
});
app.get('*', function (req, res) {
res.sendFile('index.html', {root: '.'})
})
app.listen(1337, () => console.log('Started server at http://localhost:1337!'));
There are several options for node/express, e.g. express middleware

Categories