This is my first app doing it with node.js and express. This is a basic app where I connect to an external API to show temperature and take a user input "zipcode and feeling" and show it to the UI. I can't get the data.
I ran the app and entered data in the zipcode and feeling text area, What am I doing wrong?
the server.js
// Setup empty JS object to act as endpoint for all routes
projectData = {};
const port = 3000
// Require Express to run server and routes
const express = require("express")
const bodyParser = require("body-parser")
const cors = require("cors")
// Start up an instance of app
const app = express();
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
app.use(cors())
// Initialize the main project folder
app.use(express.static('website'));
app.get('/getWeather',(req,res) => {
res.send(projectData)
})
app.post('/addWeather',(req,res) => {
newEntry = {
data:req.body.data,
temp: req.body.temp,
content: req.body.content
}
projectData = newEntry;
})
// Setup Server
app.listen(port, () => {
console.log(`Your server is running on port ${port}`);
})
website/app.js
/* Global Variables */
//const { request } = require("express");
// Create a new date instance dynamically with JS
let d = new Date();
let newDate = (d.getMonth()+1) +'.'+ d.getDate()+'.'+ d.getFullYear();
//let zipcode = document.querySelector("#zip").value;
const APIkey = "2f12ba4132bf221863be475a1a6b34f6";
//let fullURL=`https://api.openweathermap.org/data/2.5/weather?zip=${zipcode}&appid=${APIkey}$units=metric`
const button1 = document.querySelector("#generate")
button1.addEventListener("click", getDataOfWeather)
function getDataOfWeather(){
const feeling = document.querySelector("#feelings").value;
const zipcode = document.querySelector("#zip").value;
getTemp(zipcode)
.then(function(temp){
/* console.log(temp);
addData('/addWeather',{ data: newDate , temp: temp, content: feeling});*/
addData(temp,feeling)
})
.then(
updateUI()
)
}
const getTemp = async(zipcode) => {
try {
if(!zipcode){
alert("you didnot enter zip code");
}
const fullURL=`https://api.openweathermap.org/data/2.5/weather?zip=${zipcode}&appid=${APIkey}&units=metric`
const res = await fetch(fullURL)
if(res.status === 200){
const data = await res.json();
console.log(data.main.temp);
return data.main.temp;
}
else if(res.status === 404){
alert("error in ZIP code ");
return false;}
/* const data = await res.json();
return data;*/
}
catch (err)
{
console.log(err);
}
}
const addData = async(temp,fell) => {
console.log(fell);
const response = await fetch("/addWeather",{
method: "POST",
credentials: "same-origin",
body:{
data : newDate,
temp:temp,
content: fell,
}
})
try {
const nData = await response.json();
return nData;
}
catch(err)
{
console.log(err);
}
}
/*const addData = async(url = '', data = {})=> {
const response = await fetch (url , {
method: 'POST',
credentials: 'same-origin',
headers: {
'content-Type': 'application/json',
},
body: JSON.stringify(data),
})
try {
const nData = await response.json();
return nData;
}
catch(err)
{
console.log(err);
}
}*/
const updateUI = async() => {
const request = await fetch('/getWeather');
try {
const allOfData = await request.json();
console.log(allOfData);
document.getElementById('data').innerHTML = allOfData.newDate;
document.getElementById('temp').innerHTML = allOfData.temp;
document.getElementById('content').innerHTML = allOfData.content;
}
catch (err)
{
console.log("error",err);
}
}
website/index.js
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Weather Journal</title>
<link href="https://fonts.googleapis.com/css?family=Oswald:400,600,700|Ranga:400,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id = "app">
<div class ="holder headline">
Weather Journal App
</div>
<div class ="holder zip">
<label for="zip">Enter Zipcode here</label>
<input type="text" id="zip" placeholder="enter zip code here">
</div>
<div class ="holder feel">
<label for="feelings">How are you feeling today?</label>
<textarea class= "myInput" id="feelings" placeholder="Enter your feelings here" rows="3" cols="30"></textarea>
<button id="generate" type = "submit"> Generate </button>
</div>
<div class ="holder entry">
<div class = "title">Most Recent Entry</div>
<div id = "entryHolder">
<div id = "date"></div>
<div id = "temp"></div>
<div id = "content"></div>
</div>
</div>
</div>
<script src="app.js" type="text/javascript"></script>
</body>
</html>
Your Id is date not data in update UI function in app.js
const updateUI = async() => {
const request = await fetch('/getWeather');
try {
const allOfData = await request.json();
console.log(allOfData);
document.getElementById('date').innerHTML = allOfData.newDate; // change data to date
document.getElementById('temp').innerHTML = allOfData.temp;
document.getElementById('content').innerHTML = allOfData.content;
}
catch (err)
{
console.log("error",err);
}
}
Related
I am doing wether app API. I am using my API key via a server, which is working fine until I enter anything in the search box and receive my error message then server is crashing. So I am not able to extract the data from api. Anytime I am entering a valid city is the server is catching with my error message instead of getting my data. Is it possible there are issue with my server that does not allowed me extract data from api openWeather.org or the issue is with the code from the js file.
This is server file:
if(process.env.NODE_ENV !== "production") {
require("dotenv").config()
}
const API_KEY = process.env.API_KEY // the api key is stoored in ".env" file
const axios = require("axios")
const express = require("express")
const app = express()
app.use(express.json())
app.use(express.static("public"))
app.post("/data", (req, res) => {
const url = `https://api.openweathermap.org/data/2.5/weather?q=${req.body.name}&exclude=hourly,minutely&units=metric&appid=${API_KEY}`
axios({
url: url,
responseType: "json",
}).then(data => res.json(data.data.currently))
})
app.listen(3000, () => {
console.log("Server Started")
})
script file
let searchInput = document.querySelector(".search-bar");
let timeDiv = document.querySelector(".current-time");
let city = document.querySelector(".location");
let detailSection = document.querySelector(".detail-section");
let condition = document.querySelector(".status");
let tempItem = document.querySelector(".degree-section");
let currentTemp = document.querySelector(".temp");
let mgs = document.querySelector(".msg");
setInterval(() => {
const time = new Date();
const hour = time.getHours();
const min = time.getMinutes();
const ampm = hour >= 12 ? "PM" : "AM";
if(min < 10) {
timeDiv.innerHTML = `<div class="time">${hour}:0${min} <span class="am-pm">${ampm}</span></div>`;
}
else{
timeDiv.innerHTML = `<div class="time">${hour}:${min} <span class="am-pm">${ampm}</span></div>`;
}
}, 1000);
document.querySelector(".btn").addEventListener("click", (event) => {
event.preventDefault();
let cityValue = searchInput.value;
fetch("/data", {
method: 'POST',
timeout: 0,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({city: cityValue})
})
.then((response) => response.json())
.then((data) => {
this.displayWeather(data)
})
. catch(() => {
mgs.textContent = `Please enter a valid city! 😞`;
});
});
function displayWeather(data) {
const { name } = data;
const { country } = data.sys;
const { icon, description } = data.weather[0];
const { temp, humidity } = data.main;
const { speed } = data.wind;
location.textContent = `Weather in ${name},${country}`;
condition.innerHTML = `<img class="icon" scr="http://openweathermap.org/img/wn/${icon}.png" />
<div class="condition">${description}</div> `;
detailSection.innerHTML = `<div class="detail">
<div class="title">Humidity</div>
<div class="humidity">${humidity}%</div>
</div>
<div class="detail">
<div class="title">Temperature</div>
<div class="degree-section">
<div class="temp">${temp} °C</div>
</div>
</div>
<div class="detail">
<div class="title">Wind</div>
<div class="wind-speed">${speed} km/h</div>
</div>`;
tempItem.addEventListener("click", function(){
if(currentTemp.value === undefined) return;
if(data.main.temp.unit === "celsius"){
let fahrenheit = celsiusToFahrenheit(data.main.temp.value);
fahrenheit = Math.floor(fahrenheit);
tempItem.innerHTML = `<div class="temp">${fahrenheit} °F</div>`;
data.main.temp.unit = "fahrenheit";
}
else {
tempItem.innerHTML = `<div class="temp">${temp} °C</div>`;
data.main.temp.unit === "celsius"
}
})
}
function celsiusToFahrenheit(temp) {
return (temp * 9/5) + 32;
}
I changed the code from object with function elements to separate functions but still I am not able to extract the weather data with any valid city I am not sure where is the issue with the server which is working fine until i get my error message or in the fetch function. Could someone help me with this issue?
I'm building a web app using Node, Express, Cors and Body Parser. The app uses the fetch api to fetch data from online apis. Now I have written all the code with a server.js file, an index.html and an app.js. My server.js file contains the express server functions and middleware. My app.js contains the main functionality. Here are my files:
Index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Weather Journal</title>
</head>
<body>
<div id="app">
<div class="holder headline">
Weather Journal App
</div>
<form id="userInfo">
<div class="holder zip">
<label for="zip">Enter City here</label>
<input type="text" id="city" placeholder="enter city here" required>
</div>
<div class="holder feel">
<label for="date">Enter departure date</label>
<input type="datetime-local" id="date" required>
<button id="submitBtn" type="submit"> Generate </button>
</div>
</form>
<div class="holder entry">
<div class="title">Most Recent Entry</div>
<div id="entryHolder">
<div id="lat"></div>
<div id="lng"></div>
<div id="countryName"></div>
<div id="temp"></div>
</div>
</div>
</div>
<script src="app.js" type="text/javascript"></script>
</body>
</html>
My app.js:
const geoURL = "http://api.geonames.org/searchJSON?";
const geoUsername = `rohanasif1990`;
const weatherURL = "https://api.weatherbit.io/v2.0/forecast/daily?"
const weatherKey = "20028a8267a24bba9a807362767bc4a7"
let d = new Date();
let newDate = d.getMonth() + 1 + "." + d.getDate() + "." + d.getFullYear();
const submitBtn = document.getElementById("submitBtn");
submitBtn.addEventListener("click", (e) => {
e.preventDefault();
const city = document.getElementById("city").value;
if (city !== "") {
getCity(geoURL, city, geoUsername)
.then(function (data) {
getWeather(weatherURL, weatherKey, data["geonames"][0]['lat'], data["geonames"][0]['lng'])
}).then(weatherData => {
postWeatherData("/addWeather", { temp: weatherData })
}).then(function () {
receiveWeatherData()
}).catch(function (error) {
console.log(error);
alert("Invalid city");
})
}
})
const getCity = async (geoURL, city, geoUsername) => {
const res = await fetch(`${geoURL}q=${city}&username=${geoUsername}`);
try {
const cityData = await res.json();
return cityData;
}
catch (error) {
console.log("error", error);
}
}
const postWeatherData = async (url = "", data = {}) => {
const response = await fetch(url, {
method: "POST",
credentials: "same-origin",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
temp: data.temp
})
});
try {
const newData = await response.json();
return newData;
}
catch (error) {
console.log(error);
}
}
const receiveWeatherData = async () => {
const request = await fetch("/allWeather");
try {
const allData = await request.json()
document.getElementById("temp").innerHTML = allData.temp;
}
catch (error) {
console.log("error", error)
}
}
const getWeather = async (weatherURL, weatherKey, lat, lon) => {
const res = await fetch(`${weatherURL}&lat=${lat}&lon=${lon}&key=${weatherKey}`);
try {
const weatherData = await res.json();
return weatherData;
}
catch (error) {
console.log("error", error);
}
}
My server.js:
// Setup empty JS object to act as endpoint for all routes
cityData = {};
weatherData = {};
picturesData = {};
// Require Express to run server and routes
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
// Start up an instance of app
const app = express();
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
app.use(cors())
// Initialize the main project folder
app.use(express.static('website'));
app.get("/all", function sendData(req, res) {
res.send(cityData);
})
app.get("/allWeather", function sendWeather(req, res) {
res.send(weatherData);
})
app.get("allPictures", function sendPictures(req, res) {
res.send(picturesData);
})
app.post("/add", (req, res) => {
projectData['lat'] = req.body.lat;
projectData['lng'] = req.body.lng;
projectData['countryName'] = req.body.countryName
res.send(cityData);
})
app.post("/addWeather", (req, res) => {
weatherData['temp'] = req.body.temp;
res.send(weatherData);
})
app.post("/addPicture", (req, res) => {
picturesData['pic'] = req.body.pic;
res.send(picturesData);
})
// Setup Server
app.listen(3000, () => {
console.log("App listening on port 3000")
console.log("Go to http://localhost:3000")
})
I am trying to get the geonames api to fetch the latitude and longitude of a city . Then I want to use the latitude and longitude to fetch the weather for that location. The pictures api is not implemented yet. I just want to use the data fetched from one api (geonames.org) as input to the other api (weatherbit.io). Right the app returns undefined when I console.log the final data.
You are breaking the Promise then chain. You do not return any promise so that it can be chained. Pasting modified example withe capital RETURN
statements
getCity(geoURL, city, geoUsername)
.then(function (data) {
RETURN getWeather(weatherURL, weatherKey, data["geonames"][0]['lat'], data["geonames"][0]['lng'])
}).then(weatherData => {
RETURN postWeatherData("/addWeather", { temp: weatherData })
}).then(function () {
RETURN receiveWeatherData()
}).catch(function (error) {
console.log(error);
alert("Invalid city");
})
A better would be to write the function as Async, I see you have done that already
So
submitBtn.addEventListener("click", async (e) => {
e.preventDefault();
const city = document.getElementById("city").value;
if (city !== "") {
try {
const city = await getCity(geoURL, city, geoUsername);
const weatherData = await getWeather(weatherURL, weatherKey, city["geonames"][0]['lat'], city["geonames"][0]['lng']);
//and so on
} catch (e) {
console.log(error);
alert("Invalid city");
}
}
})
The problem was here:
const receiveWeatherData = async () => {
const request = await fetch("/allWeather");
try {
const allData = await request.json()
document.getElementById("temp").innerHTML = allData['temp'];
}
catch (error) {
console.log("error", error)
}
}
I replaced allData['data'] with allData['temp']
I have this api which works fine when running locally. But, once it is deployed to Heroku i get a error 503 which is because it tries to target localhost on Heroku's server and not the user's localhost. Is there a way to make this target the user's localhost instead?
The frontend is React. Here's the code in React that fetches this api every 5sec.
axiosFunc = () => {
const { user } = this.props.auth;
console.log(user);
axios.get(`api/avaya/${user.id}`).then((res) => console.log(res));
};
timer = (time) => {
const date = new Date(time);
return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
};
componentDidMount() {
this.axiosFunc();
this.interval = setInterval(this.axiosFunc, 5000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
and this is the API on the backend with express
const router = require("express").Router();
const xml2js = require("xml2js");
const Avaya = require("../../models/Avaya");
const User = require("../../models/User");
router.route("/:id").get(async (req, res) => {
const user = await User.findById(req.params.id);
const axios = require("axios");
axios({
method: "post",
baseURL: `http://127.0.0.1:60000/onexagent/api/registerclient?name=${user.username}`,
timeout: 2000,
})
.then((reg) => {
xml2js
.parseStringPromise(reg.data, { mergeAttrs: true })
.then((result) => {
if (result.RegisterClientResponse.ResponseCode[0] === "0") {
const clientId = result.RegisterClientResponse.ClientId[0];
user.avayaClientId = clientId;
user.save();
}
const clientId = user.avayaClientId;
axios({
method: "post",
url: `http://127.0.0.1:60000/onexagent/api/nextnotification?clientid=${clientId}`,
}).then((notification) => {
xml2js
.parseStringPromise(notification.data, { mergeAttrs: true })
.then((result) => {
const notifType = [];
const notifDetails = [];
for (let i in result.NextNotificationResponse) {
notifType.push(i);
}
const arranged = {
NotificationType: notifType[1],
ResponseCode:
result.NextNotificationResponse[notifType[0]][0],
};
for (let i in result.NextNotificationResponse[
notifType[1]
][0]) {
notifDetails.push(i);
}
for (let i = 0; i < notifDetails.length; i++) {
arranged[[notifDetails[i]][0]] =
result.NextNotificationResponse[notifType[1]][0][
notifDetails[i]
][0];
}
for (let i in arranged) {
if ("Outbound" in arranged) {
arranged.CallType = "Outbound";
} else if ("Inbound" in arranged)
arranged.CallType = "Inbound";
else {
arranged.CallType = " ";
}
}
if (
arranged.NotificationType === "VoiceInteractionCreated" ||
arranged.NotificationType === "VoiceInteractionMissed" ||
arranged.NotificationType === "VoiceInteractionTerminated"
) {
const newLogs = new Avaya({
notification: arranged,
});
newLogs.owner = user;
newLogs.save();
user.avayaNotifications.push(newLogs),
user
.save()
.then((logs) => res.json(logs))
.catch((err) => res.status(400).json("Error: " + err));
} else {
res.send("Nothing to record");
}
});
});
});
})
.catch((err) => res.status(503).json(err));
});
router.route("/history/:username").get(async (req, res) => {
const user = await User.findOne({ username: [`${req.params.username}`] });
Avaya.find({ owner: [`${await user.id}`] }).then((user) => res.json(user));
});
module.exports = router;
EDIT: I was able to fix thanks to #Molda
using fetch instead of axios doesn't result in cors error.
New frontend code
getLogs = async () => {
const { user } = this.props.auth;
const reg = await fetch(
`http://127.0.0.1:60000/onexagent/api/registerclient?name=${user.id}`
);
let regData = await reg.text();
let regxml = new XMLParser().parseFromString(regData);
if (regxml.attributes.ResponseCode === "0") {
axios.post(`/api/avaya/register/${user.id}`, regxml);
console.log(regxml.attributes.ResponseCode);
}
let resp = await fetch(`/api/avaya/getid/${user.id}`);
let clientId = await resp.text();
let logs = await fetch(
`http://127.0.0.1:60000/onexagent/api/nextnotification?clientid=${clientId}`
);
let data = await logs.text();
var xml = new XMLParser().parseFromString(data);
axios.post(`/api/avaya/getlogs/${user.id}`, xml);
};
timer = (time) => {
const date = new Date(time);
return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
};
componentDidMount() {
this.getLogs();
this.interval = setInterval(this.getLogs, 5000);
}
New backend code:
const router = require("express").Router();
const Avaya = require("../../models/Avaya");
const User = require("../../models/User");
router.route("/register/:id").post(async (req, res) => {
const user = await User.findById(req.params.id);
const clientId = req.body.attributes.ClientId;
user.avayaClientId = clientId;
user.save();
});
router.route("/getid/:id").get(async (req, res) => {
const user = await User.findById(req.params.id);
res.send(user.avayaClientId);
});
router.route("/getlogs/:id").post(async (req, res) => {
const user = await User.findById(req.params.id);
const arranged = {
NotificationType: req.body.children[0].name,
ResponseCode: req.body.attributes.ResponseCode,
CallType: " ",
};
for (let i in req.body.children[0].attributes) {
if (i === "Outbound") {
arranged.CallType = "Outbound";
}
if (i === "Inbound") {
arranged.CallType = "Inbound";
}
arranged[i] = req.body.children[0].attributes[i];
}
console.log(arranged);
if (
arranged.NotificationType === "VoiceInteractionCreated" ||
arranged.NotificationType === "VoiceInteractionMissed" ||
arranged.NotificationType === "VoiceInteractionTerminated"
) {
const newLogs = new Avaya({
notification: arranged,
});
newLogs.owner = user;
newLogs.save();
user.avayaNotifications.push(newLogs),
user
.save()
.then((logs) => res.json(logs))
.catch((err) => res.status(400).json("Error: " + err));
} else {
res.send("Nothing to record");
}
});
router.route("/history/:username").get(async (req, res) => {
const user = await User.findOne({ username: [`${req.params.username}`] });
Avaya.find({ owner: [`${await user.id}`] }).then((user) => res.json(user));
});
module.exports = router;
I really don't get the part of (requesting with Axios in API)
Is this a third party API ?
But I suggest you to use (.env) which is a file in your root folder contains the development config like base URLs, expire tokens, API keys ... etc
and when you upload to Heroku you have to make a (.env) in Heroku app and but your config
Let's take an example
in my development mode, my .env looks like
app_url = localhost:4000
port = 4000
db = development_api
db_username = root
db_password =
db_engine = mysql2
in my production mode, my .env looks like
app_url = http://appsomething.heroku.com
port = 80
db = production_api
db_username = root
db_password = 3210LDWAK#AALKQ
db_engine = mysql2
and read more about how to use .ENV
This question already has answers here:
How do I POST a x-www-form-urlencoded request using Fetch?
(17 answers)
Closed 2 years ago.
I want to submit a form and then return an object from my MongoDB database without reloading the page. Therefore when I submit my form I use an event handler that prevents the default behavior of the form to reload the page. The problem is this is interfering with my server side script and causing req.body to return null. If I remove e.preventDefault() from my client side script then req.body works fine but the page refreshes and just displays a json from my database. How would I get around this?
Here is my HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<title>Message in a Bottle</title>
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div id = "icon">
<img id = "iconImg" style = "width:100%"src = "icon.svg"/>
</div>
<div id = "form">
<form method="post" action="/">
<input type="text" name="sender"/>
<textarea rows="20" cols="50" name="message"></textarea>
<button type = "submit" onclick="onClick(event)">submit</button>
</form>
</div>
<div id = "message">
<p id = "senderName"></p>
<p id = "response"></p>
<button onclick="closeMessage()">New Message</button>
</div>
</body>
<script type = "text/javascript" src = "packageHandler.js"></script>
</html>
Here is my client side script:
const form = document.getElementById("form");
const icon = document.getElementById("icon");
const message = document.getElementById("message");
function onClick(e){
e.preventDefault();
console.log("loading results");
form.style.opacity = "0%";
form.style.pointerEvents = "none";
icon.style.width = "80%";
fetch('http://localhost:3000/', {method: 'POST'})
.then((response) => {
icon.style.width = "33%";
message.style.opacity = "100%";
message.style.pointerEvents = "auto";
return response.json();
})
.then((data) => {
document.getElementById("senderName").innerHTML = data.name;
document.getElementById("response").innerHTML = data.message;
});
//await results
//fade in <div id = "message">
//display results in <div id = "message">
}
function closeMessage(){
console.log("message closed")
form.style.opacity = "100%";
form.style.pointerEvents = "auto";
message.style.opacity = "0%";
message.style.pointerEvents = "none";
//fade out <div id = "message">
//fade in <div id = "form"
}
Here is my server side script:
const express = require('express');
const MongoClient = require('mongodb').MongoClient;
require('dotenv/config');
const app = express();
const fs = require('fs');
const port = 3000;
app.use(express.urlencoded());
app.use(express.static('public'));
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
//Routes
app.get('/', (req, res) => {
fs.readFile('./views/home.html', function (err, data) {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write(data);
res.end();
});
});
app.post('/', (req, res) => {
MongoClient.connect(process.env.DB_CONNECTION, { useUnifiedTopology: true, useNewUrlParser: true }, function (err, db) {
if (err) throw err;
const dbo = db.db("mydb");
const messageTable = dbo.collection("messages");
let myobj =
[{
name: req.body.sender,
message: req.body.message
}];
console.log(myobj)
messageTable.insertMany(myobj, function (err, res) {
if (err) throw err;
console.log("1 document inserted");
});
var myPromise = () => {
return new Promise((resolve, reject) => {
messageTable.aggregate(
[{ $sample: { size: 1 } }]
).toArray((err, data) => {
err
? reject(err)
: resolve(data[0]);
});
});
}
//Step 2: async promise handler
var callMyPromise = async () => {
var result = await (myPromise());
//anything here is executed after result is resolved
return result;
};
//Step 3: make the call
callMyPromise().then(function (result) {
db.close();
res.json(result)
});
});
}); //end mongo client
When you make a request with fetch the data from your form is not included.
To include the data your must manually gather the data and send it with the request.
Super lazy example:
EDIT: changed to FormData based of this answer
EDIT 2: FormData sends as multipart/form-data so we need to url-encode it first. (Thanks #Phil)
var forms = document.querySelectorAll('form');
forms.forEach((form) => form.onsubmit = onsubmit);
function onsubmit(e) {
e.preventDefault();
var form = e.target;
var formData = new FormData(form);
var encodedData = new URLSearchParams(formData).toString()
// log form values
console.log(encodedData);
fetch('/', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: encodedData
})
.then(result => {
});
}
<form method="post" action="/">
<input type="text" name="sender"/>
<textarea rows="20" cols="50" name="message"></textarea>
<button type = "submit">submit</button>
</form>
This is happening because you are using the wrong event.
Try using onsubmit event on the form and instead of using event.preventDefault(), return false in the onSubmit function.
It will look like something like this:
<form onsubmit="onSubmit()">
<button type="submit"></button>
</form>
Then the code:
function onSubmit() {
... do your thing ...
return false;
}
It should work, but If doesn't, then You will have to add formData to the body yourself. (I will tell you how if needed).
Update
Add id to the form (you don't have to, but it makes things easier.
<form id="myForm">
<button></button>
</form>
get the form data:
var formData = new FormData(document.getElementById('myForm'))
Pass them to the fetch as the request body.
fetch('url', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data'
},
body: formData
})
HHi,
I'm working on a project for an online course and I need to make one change to the project. I don't exactly understand what the code reviewer is saying I'm doing wrong. His comment is:
Here you need to fire a new GET request to fetch the data from server.
The requests GET and POST have a specific purpose.
GET request to fetch data from server/db
POST is used to create new data in server/db
These requests must do the task they are designed for, nothing else.
This is the problem area of my code:
let postData = async(url = '', data = {})=>{
console.log(data);
let temp = data.main.temp;
let zip = document.getElementById('zip').value;
let feelings = document.getElementById('feelings').value;
let date = newDate;
let response = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify( { temp, zip, feelings, date }),
});
try {
const newData = await response.json();
console.log(newData);
document.getElementById("date").innerHTML = newData.date;
document.getElementById("temp").innerHTML = newData.temp;
document.getElementById("content").innerHTML = newData.feelings;
return newData
}catch(error) {
console.log("error", error);
}
}
This is my full code:
app.js:
let apiURL = 'http://api.openweathermap.org/data/2.5/weather?id=524901&APPID=' + apiKey + '&zip=';
const endURL = ',us';
// Create a new date instance dynamically with JS
let d = new Date();
let newDate = d.getMonth()+'.'+ d.getDate()+'.'+ d.getFullYear();
document.getElementById('generate').addEventListener('click', performAction);
let content = document.getElementById('feelings').value;
function performAction(e){
let zip = document.getElementById('zip').value;
let url = apiURL + zip + endURL;
apiCall(url)
.then(async function(data){
console.log(data);
let res = await postData('/', data);
console.log(res);
});
};
const apiCall = async (url) =>{
const res = await fetch(url);
try {
const data = await res.json();
console.log(data)
return data;
} catch(error) {
console.log(error)
}
};
let postData = async(url = '', data = {})=>{
console.log(data);
let temp = data.main.temp;
let zip = document.getElementById('zip').value;
let feelings = document.getElementById('feelings').value;
let date = newDate;
let response = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify( { temp, zip, feelings, date }),
});
try {
const newData = await response.json();
console.log(newData);
document.getElementById("date").innerHTML = newData.date;
document.getElementById("temp").innerHTML = newData.temp;
document.getElementById("content").innerHTML = newData.feelings;
return newData
}catch(error) {
console.log("error", error);
}
}
server.js:
let projectData = {};
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
const bodyParser = require('body-parser');
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const cors = require('cors');
app.use(cors());
// Cors for cross origin allowance
// Initialize the main project folder
app.use(express.static('website'));
// Setup Server
const port = 8000;
const server = app.listen(port, listening);
function listening(){
console.log(`running on localhost: ${port}`);
};
app.get('/weather', getData);
function getData(req, res){
res.send(projectData)
console.log(projectData)
};
app.route('/')
.get(function (req, res) {
res.sendFile('index.html', {root: 'website'})
})
.post(getWeather);
function getWeather(req, res){
console.log(req.body);
projectData = req.body;
console.log(projectData);
res.status(200).send(projectData);
};
I have no idea what the changes would look like because I wrote this code following the same structure that they taught in the lessons. Any help would be greatly appreciated.
Thanks alot,
Mike
I think you are trying to fetch data from API so he is trying to say that when you are trying to fetch data from api you need GET request.
I figured it out. I needed to write this function:
const updateUI = async () =>{
const res = await fetch('/weather');
try {
const allData = await res.json();
console.log(allData)
document.getElementById("date").innerHTML = allData.date;
document.getElementById("temp").innerHTML = allData.temp;
document.getElementById("content").innerHTML = allData.feelings;
return allData
} catch(error) {
console.log(error)
}
};
and edit my postData function to this:
let postData = async(url = '', data = {})=>{
console.log(data);
let temp = data.main.temp;
let zip = document.getElementById('zip').value;
let feelings = document.getElementById('feelings').value;
let date = newDate;
let response = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify( { temp, zip, feelings, date }),
});
try {
updateUI()
/* const newData = await response.json();
console.log(newData);
document.getElementById("date").innerHTML = newData.date;
document.getElementById("temp").innerHTML = newData.temp;
document.getElementById("content").innerHTML = newData.feelings;
return newData
*/
}catch(error) {
console.log("error", error);
}
}