UI update with GET method - javascript

I'm working on a project to get the api from openweathermap using node js & express & then update the UI.
I'm trying to update the UI of the page with the GET data, but it does not work. it prints undefined instead of the required values.
it works and gets the api from openweathermap on the terminal & console.
any help would be appreciated!
/* Global Variables */
const date = document.getElementById('date').value;
const temp = document.getElementById('temp').value;
// Create a new date instance dynamically with JS
let d = new Date();
let newDate = d.getMonth()+'.'+ d.getDate()+'.'+ d.getFullYear();
//baseURL & apiKey
const baseURL = `http://api.openweathermap.org/data/2.5/weather?zip=`;
const apiKey = `&appid=...`;
//event listener when user clicks generate button
const button = document.getElementById('generate');
button.addEventListener('click', performAction);
//event listener function
function performAction(event) {
const zip = document.getElementById('zip').value;
const feelings = document.getElementById('feelings').value;
getData(baseURL, zip, apiKey)
.then(function (data) {
console.log(data);
postData('/add', {date: newDate, temp: data.main.temp, feelings: feelings});
updateUI();
})
};
//function to fetch api data
const getData = async (baseURL, zip, apiKey) => {
const res = await fetch(baseURL+zip+apiKey)
try {
const data = await res.json();
return data;
console.log(data);
}catch(error) {
console.log("error", error);
}
}
// user input post data function
const postData = async (url = '', data = {}) => {
const response = await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
try {
const newData = await response.json();
}catch (error) {
console.log("error", error);
}
};
//updating UI
const updateUI = async () => {
const request = await fetch('/all');
try{
const allData = await request.json();
document.getElementById('date').innerHTML = allData.date;
document.getElementById('temp').innerHTML = allData.temp;
document.getElementById('content').innerHTML = allData.content;
}catch(error){
console.log("error", error);
}
}

Related

400 "Bad Request" error when using Thunder Client (Postman) API

I am using the Thunder Client app for VS code to use an API to save the user's data. The API is okay but there is something wrong with my code because I keep getting a 400 "Bad Request" error when I try to send the data to the API. I think the problem might be an array in my code and that is not being sent correctly.
const form = document.querySelector('.form');
const refresh = document.querySelector('.refresh-button');
export const scores = [];
renderScores();
// event listener
form.addEventListener('submit', (e) => {
e.preventDefault();
saveScore();
renderScores();
});
refresh.addEventListener('click', (e) => {
e.preventDefault();
getScores();
renderScores();
});
function renderScores() {
const scoreList = document.querySelector('.result-list');
scoreList.innerHTML = '';
scores.forEach((score) => {
const li = document.createElement('li');
li.innerHTML = `${score.user} : ${score.score}`;
scoreList.appendChild(li);
});
}
async function getScores() {
const savedScores = 'https://us-central1-js-capstone-backend.cloudfunctions.net/api/games/Zl4d7IVkemOTTVg2fUdz/scores/';
const recievedScores = await fetch(savedScores);
const api = await recievedScores.json();
const scores = api.result;
renderScores(scores);
}
async function saveScore() {
const user = document.querySelector('.fullname').value;
const score = document.querySelector('.thescore').value;
const newScore = {
user,
score,
};
scores.push(user, score);
await fetch('https://us-central1-js-capstone-backend.cloudfunctions.net/api/games/Zl4d7IVkemOTTVg2fUdz/scores/', {
method: 'POST',
body: JSON.stringify({
newScore
}),
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
});
getScores();
}
Hey guys I changed my code a little and now I am not getting an error but when I refresh my page I lose all the data

I want to use for loop in async function with "thens" in javascript

I'm creating a simple web app that fetches data asynchronously from three web apis. One is for location, one for weather and one for stock images. My files are as follow:
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="city">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">Details</div>
<div>
<img id="city-pic" src="" alt="your city">
</div>
<div id="entryHolder">
<div><b>Temperature for next 16 days:</b></div>
<ul id="entries">
<div id="temp"></div>
<div id="time"></div>
</ul>
</div>
</div>
</div>
<script src="app.js" type="text/javascript"></script>
</body>
</html>
app.js:
const present = new Date();
const submitBtn = document.getElementById("submitBtn");
submitBtn.addEventListener("click", (e) => {
e.preventDefault();
const city = document.getElementById("city").value;
const departure = document.getElementById("date").value;
const [depart_date, depart_time] = departure.split("T")
const [depart_year, depart_month, depart_day] = depart_date.split("-")
const [depart_hour, depart_minute] = depart_time.split(":")
const future = new Date(depart_year, depart_month - 1, depart_day, depart_hour, depart_minute);
if (city !== "" || departTime !== "" || future < present) {
document.getElementById("time").innerHTML = `Departure in ${Math.ceil((future - present) / 3600000 / 24)} days`
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['data'][i]['temp'], datetime: weatherData['data'][i]['datetime'] })
}).then(function () {
return receiveWeatherData()
}).catch(function (error) {
console.log(error);
alert("Please enter a valid city and a valid time");
})
getPictures(city, pixabayURL, pixabayKey)
.then(function (picsData) {
const total = picsData['hits'].length
const picIndex = Math.floor(Math.random() * total)
return postPictureData("/addPicture", { pic: picsData['hits'][picIndex]["webformatURL"] })
})
.then(function () {
return receivePictureData()
}).catch(function (error) {
console.log(error);
alert("No pictures found")
})
}
})
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,
datetime: data.datetime
})
});
try {
const newData = await response.json();
console.log(newData)
return newData;
}
catch (error) {
console.log(error);
}
}
const receiveWeatherData = async () => {
const request = await fetch("/allWeather");
try {
const allData = await request.json()
const node = document.createElement("li");
const textnode = document.createTextNode("DATE: " + allData['datetime'] + "\t" + "TEMPERATURE: " + allData['temp']);
node.appendChild(textnode);
document.getElementById("entries").appendChild(node);
}
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);
}
}
const getPictures = async (city, pixabayURL, pixabayKey) => {
const query = city.split(" ").join("+");
const res = await fetch(`${pixabayURL}key=${pixabayKey}&q=${query}`);
try {
const picsData = await res.json();
return picsData;
}
catch (error) {
console.log("error", error)
}
}
const receivePictureData = async () => {
const request = await fetch("/allPictures");
try {
const allData = await request.json()
document.getElementById("city-pic").src = allData['pic'];
}
catch (error) {
console.log("error", error)
}
}
const postPictureData = async (url = "", data = {}) => {
const response = await fetch(url, {
method: "POST",
credentials: "same-origin",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
pic: data.pic
})
});
try {
const newData = await response.json();
return newData;
}
catch (error) {
console.log(error);
}
}
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('dist'));
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("/addWeather", (req, res) => {
weatherData['temp'] = req.body.temp;
weatherData['datetime'] = req.body.datetime;
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")
})
The server uses node, express, cors, and body-parser as the tools to create it.
I have not included the api keys or usernames. Right now I need to loop over the weather data that is return from the api (which fetches 16 days of data). The code :
.then(weatherData => {
return postWeatherData("/addWeather", { temp: weatherData['data'][i]['temp'], datetime: weatherData['data'][i]['datetime'] })
should use the 'i' variable to loop over all the possible 16 entries for a certain location. Right now if run the app with 0 in place of 'i' it just gives the temperature for the next day. I want to get the weather data for 16 days and append it to the html 'ul' that I have in the document. Can someone guide me. This is the last step in the project that I need to complete by 10 november!
EDIT:
I tried using this and subsituted forLoop() instead the 'thens' but i get an error:
const forLoop = async () => {
for (i = 0; i < 16; i++) {
try {
coords = await getCity(geoURL, city, geoUsername)
weatherData = await getWeather(weatherURL, weatherKey, coords["geonames"][0]['lat'], coords["geonames"][0]['lng'])
await postWeatherData("/addWeather", { temp: weatherData['data'][i]['temp'], datetime: weatherData['data'][i]['datetime'] })
await receiveWeatherData(i);
}
catch (error) {
console.log(error);
// alert("Please enter a valid city and a valid time");
}
}
}
The error is: "16app.js:156 TypeError: Cannot read properties of undefined (reading 'lat')
at forLoop (app.js:150:89)"
A series of promises can be created using Array.map() over received weather data, and a series of promises can be resolved using Promise.all(). The returned output would be an array of received temperature information. Please see the below code
(PromiseLikeObject)
.then(weatherData => {
const promiseCollection = weatherData['data'].map(d => postWeatherData("/addWeather", { temp: d.temp, datetime: d.datetime }));
return Promise.all(promiseCollection);
});
If I understood you right, I think you could just map over the data and display it in DOM, just adjust the to the array you receive.
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,
datetime: data.datetime
})
});
try {
const newData = await response.json();
let entryHolder = document.getElementById("entryHolder");
const weather = newData.map((data, index) => {
return `<ul id="entries">
<div id="temp">${data.temp}</div>
<div id="time">${data.time}</div>
</ul>`
}).join('')
entryHolder.innerHTML = weather
}
catch (error) {
console.log(error);
}
}
I have fixed it with for loop:
const forLoop = async () => {
for (i = 0; i < 16; i++) {
try {
const city = await document.getElementById("city").value;
const coords = await getCity(geoURL, city, geoUsername)
const weatherData = await getWeather(weatherURL, weatherKey, coords["geonames"][0]['lat'], coords["geonames"][0]['lng'])
postWeatherData("/addWeather", { temp: weatherData['data'][i]['temp'], datetime: weatherData['data'][i]['datetime'] })
receiveWeatherData(i)
}
catch (error) {
console.log(error);
// alert("Please enter a valid city and a valid time");
}
}
}

how to call api recursively until nested stack keys are finished

here is my question how to call api recursively untill nested data stack keys are finished
here is my full explaination in image
i found this relatable code for recursion api call at this post recursive api call
function callFW() {
d3.json(url, async function(data) {
Tree["uid"] = data.request.uid
Tree["hid"] = data.firmware.meta_data.hid
Tree["size"] = data.firmware.meta_data.size
Tree["children"] = [];
await BuildTree(data.firmware.meta_data.included_files,Tree["children"]);
console.log(Tree)
})
}
async function BuildTree(included_files, fatherNode) {
if (included_files.length > 0) {
let promises = included_files.map( item => {
let url = endpoint + "file_object/" + item + "?summary=true";
return axios.get(url)
});
const results = await Promise.all(promises);
for(let response of results){
var node = {}
node["uid"] = response.data.request.uid
node["hid"] = response.data.file_object.meta_data.hid
node["size"] = response.data.file_object.meta_data.size
node["children"] = []
fatherNode.push(node)
await BuildTree(response.data.file_object.meta_data.included_files, node["children"]);
};
}
};
this is im using custom useRecurseFetch for getting post api result
but i have no idea how to change this code for recursive api call
import React from 'react';
import qs from 'qs';
import axios from 'axios';
const useRecurseFetch = query => {
const [status, setStatus] = React.useState('idle');
const [result, setResult] = React.useState([]);
const [findClass, setFindClass] = React.useState([]);
// console.log(passVariable);
var data;
data = qs.stringify({
query: `http://www.blabla{ ${query}/category}`,
});
// eslint-disable-next-line no-undef
var Grant = process.env.REACT_APP_GRANT;
// eslint-disable-next-line no-undef
var Client = process.env.REACT_APP_CLIENT;
// eslint-disable-next-line no-undef
var Key = process.env.REACT_APP_KEY;
// eslint-disable-next-line no-undef
var Auth = process.env.REACT_APP_AUTH;
// eslint-disable-next-line no-undef
var Query = process.env.REACT_APP_QUERY;
const queryCall = React.useCallback(
async token => {
if (!token) {
return;
} else {
setStatus('Loading');
var config = {
method: 'POST',
url: `${Query}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization:
token.data.token_type + ' ' + token.data.access_token,
},
data: data,
};
axios(config)
.then(response => {
setResult(response.data.results.bindings);
let originalResult = response.data.results.bindings
.filter(ek => ek.class !== undefined && ek)
.map(el => el.obj.value);
setFindClass(originalResult);
setStatus('success');
})
.catch(function (error) {
setStatus('error');
});
}
},
[data]
);
React.useEffect(() => {
const authInitiate = () => {
var data = qs.stringify({
grant_type: `${Grant}`,
client_id: `${Client}`,
client_secret: `${Key}`,
});
var config = {
method: 'POST',
url: `${Auth}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
data: data,
};
axios(config)
.then(response => {
queryCall(response);
})
.catch(function (error) {
console.log(error);
});
};
authInitiate();
}, [queryCall]);
return [status, result, findClass];
};
export default useRecurseFetch;
please any one can help me out with this code, im unable to figure out whats going in this code
anyhelp is really saved my day and really so appreciatable
here i called useRecurseFetch custom function in app.js
const [loadingStatus, mainData, addDataToPostItemArray] = useRecurseFetch(
`<kk:cat>`
);
please any one can help me out please im stuck with this process of calling api

Unhandled Promise Rejection: TypeError: undefined is not an object (evaluating 'data.date')

I keep getting this error in my code how I could fix it
// Personal API Key for OpenWeatherMap API
const COUNTRY = 'us';
const API_KEY = 'some key';
const BASE_URL = 'http://api.openweathermap.org/data/2.5/weather';
const MY_SERVER_URL = 'http://localhost:3000';
// Event listener to add function to existing HTML DOM element
document.getElementById('generate').addEventListener('click', performAction);
/* Function called by event listener */
function performAction(e) {
const zip = document.getElementById('zip').value;
const feelings = document.getElementById('feelings').value;
getWeather(zip, feelings);
}
/* Function to GET Web API Data*/
/* Function to POST data */
/* Function to GET Project Data */
const getWeather = async (zip, feelings) => {
const res =
fetch(`${BASE_URL}?APPID=${API_KEY}&zip=${zip},${COUNTRY}`) // GET
.then(response => response.json())
.then(data => {
// Add data
const tempKelvin = data.main.temp;
const d = new Date();
const formattedDate = d.getMonth() + '.' + d.getDate() + '.' + d.getFullYear();
return postData(`${MY_SERVER_URL}/addData`, { // POST
date: formattedDate,
temperature: tempKelvin,
feelings: feelings,
});
})
.then(() => fetch(`${MY_SERVER_URL}/all`)) // GET returns the fetch promise
.then(response => response.json())
.then(allData => {
// *********************************
// here is my problem
// *********************************
const data = allData[allData.length - 1];
document.getElementById('date').innerHTML = data.date;
document.getElementById('temp').innerHTML = formatTemperature(data.temperature);
document.getElementById('content').innerHTML = data.feelings;
});
}
function formatTemperature(tempKelvin) {
const celcius = tempKelvin - 273.15;
const fahrenheit = celcius * (9/5) + 32;
return `${celcius.toFixed(0)} C/${fahrenheit.toFixed(1)} F`;
}
function postData(url = '', data = {}) {
return fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
}
You response seems to be returning empty array. As a quick fix you can simply add a check for that
// Event listener to add function to existing HTML DOM element
document.getElementById('generate').addEventListener('click', performAction);
/* Function called by event listener */
function performAction(e) {
const zip = document.getElementById('zip').value;
const feelings = document.getElementById('feelings').value;
getWeather(zip, feelings);
}
/* Function to GET Web API Data*/
/* Function to POST data */
/* Function to GET Project Data */
const getWeather = async (zip, feelings) => {
const res =
fetch(`${BASE_URL}?APPID=${API_KEY}&zip=${zip},${COUNTRY}`) // GET
.then(response => response.json())
.then(data => {
// Add data
const tempKelvin = data.main.temp;
const d = new Date();
const formattedDate = d.getMonth() + '.' + d.getDate() + '.' + d.getFullYear();
return postData(`${MY_SERVER_URL}/addData`, { // POST
date: formattedDate,
temperature: tempKelvin,
feelings: feelings,
});
})
.then(() => fetch(`${MY_SERVER_URL}/all`)) // GET returns the fetch promise
.then(response => response.json())
.then(allData => {
if(!allData.length) {
console.error("Empty array");
return;
}
*italic* >quote here is the problem I have
const data = allData[allData.length - 1];
document.getElementById('date').innerHTML = data.date;
document.getElementById('temp').innerHTML = formatTemperature(data.temperature);
document.getElementById('content').innerHTML = data.feelings;
});
}
function formatTemperature(tempKelvin) {
const celcius = tempKelvin - 273.15;
const fahrenheit = celcius * (9/5) + 32;
return `${celcius.toFixed(0)} C/${fahrenheit.toFixed(1)} F`;
}
function postData(url = '', data = {}) {
return fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
}

How can I get my mongoose collection data displayed on the client side?

I am trying to fetch the data from my mongoose collection, and dispaly that data on client side. But I am getting 'Object' on the cilent side instead of data, but the data is saved in the database.
Can anyone help me, Thanks
This is my code
router.js
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/Library', { useNewUrlParser: true });
const api_list = new mongoose.Schema({
data:Array
});
const api = mongoose.model('api_listLs', api_list);
router.post('/api/list/Post', (request, response) => {
const data = request.body
const apiList = new api({data:data});
apiList.save().then(() => {
console.log(data)
response.json(data);
}).catch(() => {
response.status(400).send("Item was not send to the database")
});
});
router.get('/api/list/Get', (request, response) => {
api.find({},(err,data)=> {
if(err){
response.end();
return;
}
response.json(data);
});
});
page1.js
I used a fetch 'POST' method to pass data into database. And save it in a collection
function TableRow() {
let items = 'hey'
let domore = 'hi'
let cells = document.querySelectorAll('#recieve-info td');
cells.forEach(cell => cell.onclick = async function () {
let prevcell = cell.previousElementSibling;
if (prevcell) {
let data = {items, domore}
let options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
};
const response = await fetch('/api/list', options);
const json = await response.json();
console.log(json);
}
});
}
page2.js
Here I used fetch 'GET' method to to retreive data from database and show it on client side
async function ParaG() {
const response = await fetch('/api/list');
const data = await response.json();
console.log(data);
alert(data);
for (item of data) {
const para = document.querySelector('.Second-Para');
para.innerHTML += `${item.data}, ${item.data}`
}
}
'.Second-Para' is a p element in a container 'div'
Here is the output. I am getting 'Object' instead of data
This app pass data from one page to another by onclick
result is in data key and data is array of objects so use {data} to access the data like this:
async function ParaG() {
const response = await fetch('/api/list');
const {data} = await response.json();
console.log(data);
alert(data);
for (item of data) {
let info = item.data[0];//access to data
const para = document.querySelector('.Second-Para');
para.innerHTML += `${info.items}, ${info.domore}`
}
}

Categories

Resources