I have a express.js route whose code is below: -
const path = require("path");
const express = require("express");
const hbs = require("hbs");
const weather = require("./weather");
const app = express();
app.get("/weather", (req, res) => {
if (!req.query.city) {
return res.send({
error: "City Not Found",
});
}
res.send({
currentTemp: weather.temp,
});
});
And I also have a file to fetch data from api using axios whose code is here
const axios = require("axios");
axios
.get(
"https://api.openweathermap.org/data/2.5/weather?q=samalkha&appid=91645b79f9eac8808153c90472150f2d"
)
.then(function (response) {
module.exports = {
temp: response.data.main.temp
}
})
.catch(function (error) {
console.log("Error Spotter");
});
As I am using res.send I should get a json with currentTemp and the value of current temp should be temperature that I will get from weather.js file but I am getting a blank json array.
Try this.
You'll get the temperature in the localhost:3000
If you want to render the data for EJS (or something) instead of .then((data) => res.json(data.main.temp)) use:
.then((data) => res.render("index", { weather: data })
--
const URL =
"https://api.openweathermap.org/data/2.5/weather?q=samalkha&appid=91645b79f9eac8808153c90472150f2d"
const express = require("express")
const axios = require("axios")
const app = express()
const PORT = 3000
app.get("/", (req, res) => {
axios
.get(URL)
.then((response) => response.data)
.then((data) => res.json(data.main.temp))
.catch((err) => console.log(err))
})
app.listen(PORT, () => {
console.log(`Listening at http://localhost:${PORT}`)
})
module.exports is processed when the module is being defined. when you import weather, it does not exists therefore you get no data.
try to export a function which does the request and add a callback function as argument so you can pass the request result to it.
Change your weather.js to the following example:
const axios = require("axios");
let temperature;
async function getTemp() {
await axios
.get("https://api.openweathermap.org/data/2.5/weather?q=samalkha&appid=91645b79f9eac8808153c90472150f2d")
.then(function (response) {
temperature = response.data.main.temp
})
.catch(function (error) {
console.log("Error Spotter");
});
}
module.exports = {
temp: getTemp
}
This will actually return the fetched temperature.
Related
I would like to scrape multiple websites using NodeJS, Express, Cheerio and Axios.
I'm able now to scrape 1 website and display the information to the HTML.
But when I try to scrape multiple websites looking for the same element, it doesn't go through the forEach (stops after 1 cycle). Notice my loop which doesn't work correctly:
urls.forEach(url => {
2 files that are the most important:
index.js
const PORT = 8000
const axios = require('axios')
const cheerio = require('cheerio')
const express = require('express')
const app = express()
const cors = require('cors')
app.use(cors())
const urls = ['https://www.google.nl','https://www.google.de']
// const url = 'https://www.heineken.com/nl/nl/'
app.get('/', function(req, res){
res.json('Robin')
})
urls.forEach(url => {
app.get('/results', (req, res) => {
axios(url)
.then(response => {
const html = response.data
const $ = cheerio.load(html)
const articles = []
$('script', html).each(function(){
const link = $(this).get()[0].namespace
if (link !== undefined) {
if (link.indexOf('w3.org') > -1) {
articles.push({
link
})
}
}
})
res.json(articles)
}).catch(err => console.log(err))
})
})
app.listen(PORT, () => console.log('server running on PORT ${PORT}'))
App.js:
const root = document.querySelector('#root')
fetch('http://localhost:8000/results')
.then(response => {return response.json()})
.then(data => {
console.log(data)
data.forEach(article => {
const title = `<h3>` + article.link + `</h3>`
root.insertAdjacentHTML("beforeend", title)
})
})
You're registering multiple route handlers for the same route. Express will only route requests to the first one. Move your URL loop inside app.get("/results", ...)...
app.get("/results", async (req, res, next) => {
try {
res.json(
(
await Promise.all(
urls.map(async (url) => {
const { data } = await axios(url);
const $ = cheerio.load(data);
const articles = [];
$("script", html).each(function () {
const link = $(this).get()[0].namespace;
if (link !== undefined) {
if (link.indexOf("w3.org") > -1) {
articles.push({
link,
});
}
}
});
return articles;
})
)
).flat() // un-nest each array of articles
);
} catch (err) {
console.error(err);
next(err); // make sure Express responds with an error
}
});
I have two functions in functions.js - postData and startProcess. I am calling both functions in a function in server.js called sendData. sendData is then called in the app.post route.
In sendData, getData is called first and returns an id. This id is passed to startProcess and after it is run, a message that says 'success` should be printed. If it fails, a message that says 'failed to complete process should be returned'.
It seems like postData runs successfully, but startProcess is unable to pick or use its response as id.
When I run just the postData function in SendData, I get this error message:
JSON.stringify(value);
TypeError: Converting circular structure to JSON
What am I missing and how can I properly implement this?
functions.js
const axios = require("axios");
const BASE_URL = "http://localhost:1770";
const startProcess = async (id) => {
const headers = {
"Content-type": "application/json",
};
try {
return axios.post(`${BASE_URL}/start/${id}`, { headers });
} catch (error) {
console.error(error);
}
};
const postData = async (body) => {
const headers = {
"Content-type": "application/json",
};
try {
return axios.post(`${BASE_URL}/data`, body, { headers });
} catch (error) {
console.error(error);
}
};
server.js
const express = require("express");
const process = require("./functions.js");
const payload = require("./payload.json");
const res = require("express/lib/response");
// Create Express Server
const app = express();
app.use(cors());
// Configuration-api
const PORT = 5203;
app.use(express.json());
const sendData = async (req, res, next) => {
const body = payload;
try {
const response = await process.postData(body);
if ((response.status = 200)) {
let id = response.data;
const processResult = await process.startProcess(id);
if ((processResult.status = 200)) {
res.send("successfully started process");
}
}
} catch (error) {
console.error(error);
}
};
app.post("/data", sendData);
app.listen(PORT, () => {
console.log(`Running this application on the PORT ${PORT}`);
});
Im stuck at something very trivial trying to build my frontend.
My main.js looks like this :
const textfield = document.getElementById('inpTextField')
const btnSendPost = document.getElementById('btnSendPost')
btnSendPost.addEventListener('click', () => {
sendData()
})
function sendData() {
let txtValue = textfield.value
console.log(txtValue)
let sendingJSON = {
"body" : `${txtValue}`
}
fetch("http://localhost:3000/post", {
method: "post",
body: JSON.stringify(sendingJSON),
headers: { "Content-Type": "application.json"}
})
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.log(err))
}
but my backend (express 4.18) doesnt register POST request, and console gives back enigmatic :
TypeError: Failed to fetch
at <anonymous>:1:876
at sendData (main.js:17:5)
at HTMLButtonElement.<anonymous> (main.js:7:5)
index.js (backend)
const express = require('express')
const app = express()
const port = 3000
const bp = require('body-parser')
let randomJson = {
"apple" : "cider viegar"
}
app.use(bp.json())
app.use(bp.urlencoded(({ extended: true})))
app.get('/',(req,res) => {
res.json(randomJson)
})
app.post('/post', (req, res) => {
var body = req.body
console.log(body)
res.send("ok")
})
app.listen(port, () => {
console.log(`Server running on ${port}`)
})
any ideas ?
Whenever I make an axios call to an the '/login' endpoint, I keep getting the following error printed in my browser console. I've included the server.js file and the file from where I'm making the call for your reference.
Dependencies installed in the client folder: axios, react, react-dom, react-router-dom
Dependencies installed in the server folder: cors, express, node, spotify-web-api-node
GET http://localhost:3001/login net::ERR_EMPTY_RESPONSE
index.js file
import axios from 'axios'
const Profile = () => {
const login = () => {
console.log("testing login function - client")
axios.get("http://localhost:3001/login")
.then(() => {
console.log("success")
})
.catch(() => {
console.log("error")
})
}
return (
<div className="profile">
.
.
.
<div className="button">
<button onClick={() => login()} className="btn">Log In</button>
</div>
</div>
</div>
)
}
export default Profile
server.js file
const SpotifyWebAPINode = require('spotify-web-api-node')
const express = require('express')
const cors = require("cors")
const app = express()
app.use(cors)
// This file is copied from: https://github.com/thelinmichael/spotify-web-api-node/blob/master/examples/tutorial/00-get-access-token.js
const scopes = [
'user-top-read',
'user-library-read',
'playlist-read-private',
'playlist-read-collaborative',
'playlist-modify-public',
'playlist-modify-private',
]
// credentials are optional
var spotifyApi = new SpotifyWebAPINode({
clientId: 'XXX',
clientSecret: 'XXX',
redirectUri: 'http://localhost:3001/callback',
})
app.get('/login', (req, res) => {
console.log("testing login endpoint - server")
res.redirect(spotifyApi.createAuthorizeURL(scopes))
})
app.get('/callback', (req, res) => {
const error = req.query.error
const code = req.query.code
const state = req.query.state
if (error) {
console.error('Callback Error:', error)
res.send(`Callback Error: ${error}`)
return
}
spotifyApi
.authorizationCodeGrant(code)
.then((data) => {
const access_token = data.body['access_token']
const refresh_token = data.body['refresh_token']
const expires_in = data.body['expires_in']
spotifyApi.setAccessToken(access_token)
spotifyApi.setRefreshToken(refresh_token)
console.log('access_token:', access_token)
console.log('refresh_token:', refresh_token)
console.log(
`Sucessfully retreived access token. Expires in ${expires_in} s.`,
)
res.send('Success! You can now close the window.')
setInterval(async () => {
const data = await spotifyApi.refreshAccessToken()
const access_token = data.body['access_token']
console.log('The access token has been refreshed!')
console.log('access_token:', access_token)
spotifyApi.setAccessToken(access_token)
}, (expires_in / 2) * 1000)
})
.catch((error) => {
console.error('Error getting Tokens:', error)
res.send(`Error getting Tokens: ${error}`)
})
})
app.listen(3001, () => {
console.log('Server live on port 3001')
})
I am trying to make a request to 3rd party API, and then show it to the user on the website. I am using Gatsby and Node.js. But I have some problem passing data from server to client.
This code is responsible for making a request to the server :
import React from "react"
import axios from "axios"
const Test = () => {
const getDataFromServer = async () => {
try {
const resp = await axios.get("http://localhost:8080/data")
console.log("From frontend:" + resp.data)
} catch (err) {
console.log(err)
}
}
return (
<div>
<button onClick={getDataFromServer}>Get Data</button>
</div>
)
}
export default Test
And here code responsible to make request to 3rd party API from Node:
require("dotenv").config()
const morgan = require("morgan")
const axios = require("axios")
const express = require("express")
const cors = require("cors")
const dataRoutes = require("./routes/dataRoute")
const app = express()
app.use(cors())
app.use("/api", dataRoutes)
app.use(morgan("dev"))
const api = `${process.env.GATSBY_API_URL}?key=${process.env.GATSBY_API_KEY}&scope=jobPost&fields=name,ingress,startDate,endDate,logo`
const axiosInstance = axios.create({
baseURL: api,
})
app.get("/data", async (req, res, next) => {
try {
const response = await axiosInstance.get("/<path>")
return response.data
} catch (error) {
console.log(error)
}
})
app.listen(8080, () => {
console.log("server is listening on port 8080")
})
I retrieve data from API but when I want to pass it to a client then nothing happening.
Thank you in advance! :)