My script, this should be showing the Name of game computers in html but it does not, I have been trying so much andI betit will just be something stupid that is wrong or missing
Console says : TypeError: data is undefined
The console does show me retrieving the data works
"use strict";
window.addEventListener("load", Init);
function Init() {
fetch("https://howest-gp-wfa.github.io/st-2021-1-S2-a-wfa-pe03-Jonas-Bundervoet/api/products.json")
.then(function(response) { return response.json(); })
.then(data => console.log(data))
.then(function(data){
tester(data)
})
.catch(err => console.log(err));
window.addEventListener("load", tester);
}
My function to show data on screen (shows nothing)
function tester(data)
{
let div = document.getElementById("test");
for (var i = 0; i < data.length; i++) {
let article = document.createElement("h1");
article.innerHTML = 'Name: ' + data.GameComputers[0].Name;
div.appendChild(article);
};
}
In HTML I just have this in my body
<div id="test"></div>
console.log returns undefined
.then(data => console.log(data))
.then(function(data){
tester(data)
Your first then returns the return value of console.log which is undefined.
So your second then recieves undefined as its data.
Don't use multiple then callbacks here.
.then(function(data){
console.log(data)
tester(data)
The JSON doesn't consist of an array
The JSON you are looking at returns an object.
It doesn't have a length.
for (var i = 0; i < data.length; i++) {
… is going to fail immediately.
You've got data.GameComputers[0] so I'm guessing you want to loop over GameComputers so:
Check the length of that: i < data.GameComputers.length
Make use of i when you read it: data.GameComputers[i].Name;
Related
I'm working on my front-end, and I've arrived at a roadblock. I'm trying to fetch data from my back-end, and it is actually fetching the data. But only after everything else? I'll show you.
$(function(){
function GetURLId() {
var url = window.location.href;
var path = url.substring(url.lastIndexOf('/') + 1);
var id = path.substring(path.lastIndexOf('?id=') + 4, path.lastIndexOf("?id") + 5)
return id;
}
var url = 'https://localhost:5001/api/rental/byId/' + GetURLId();
fetch(url)
.then((resp) => resp.json())
.then(function(data) {
Object.keys(data).forEach(key => {
console.log(`${key}: ${data[key]}`);
})
});
});
So first I get which id I'm working with out of the URL. Then where the problem lays is the code under it. I'm able to fetch my data as it console.logs this:
id: 2
status: "Open"
damage: true
So the data does actually fetch from my back-end. But now, everytime I try to save the data it goes undefined. I've tried:
$(function(){
var rental = []; // Added an array
var url = 'https://localhost:5001/api/rental/byId/' + GetURLId();
fetch(url)
.then((resp) => resp.json())
.then(function(data) {
Object.keys(data).forEach(key => {
console.log(`${key}: ${data[key]}`);
rental.push(rental[key] = data[key]);
})
});
console.log(rental['id']); // Returns undefined
});
And:
var rental = []; // Added an array outside of the function
$(function(){
var url = 'https://localhost:5001/api/rental/byId/' + GetURLId();
fetch(url)
.then((resp) => resp.json())
.then(function(data) {
Object.keys(data).forEach(key => {
console.log(`${key}: ${data[key]}`);
rental.push(rental[key] = data[key]);
})
});
console.log(rental['id']); // Returns undefined
});
But! With the last one where the rental is outside of the function, I can actually call it in the console. And in the console it actually does return the value.
Inside Console:
> rental["id"]
< 2
Lastly I've tried to check the value of the key and value inside of the fetch, like this:
$(function(){
var url = 'https://localhost:5001/api/rental/byId/' + GetURLId();
fetch(url)
.then((resp) => resp.json())
.then(function(data) {
Object.keys(data).forEach(key => {
if(key == "status" && data[key] != "Reserved") {
console.log(`${key}: ${data[key]}`); // Returns damage: undefined 3 times
}
})
});
});
But this as well doesn't work. It returns damage: undefined 3 times in console.
So if anyone knows what is going on here it would be awesome!
Thanks alot in advance.
Fetch requests are asynchronous. This means that when you call fetch it might take a while to complete it, so JavaScript allows the rest of the code to continue without blocking. So logging anything to the console before your request has finished will obviously result in an empty array.
Also, Arrays are index-, not name based in JavaScript. However, because arrays are essentially objects it still works, but you should never do the following below.
var rental = [];
rental['id'] = 'foo';
console.log(rental['id']);
Instead use a plain object which is meant to be used that way.
var rental = {};
rental['id'] = 'foo';
console.log(rental['id']);
In your last example you seem to do everything just fine. Are you sure your fetched data does not have a value of undefined in its structure? It would help to see what the data looks like.
The answer: 2 errors in my code.
- First I didn't properly account for the asynchronous nature of the code.
- Second, when trying to fix it with another then block and executing my code in there. I didn't return a value in the proceeding then block, but the forEach instead.
fetch(url)
.then(resp => resp.json())
.then(data => {
var rentalStatus;
Object.keys(data).forEach(key => {
rental[key] = data[key];
if(key == "status") {
rentalStatus = data[key];
}
})
return rentalStatus;
})
.then(rentalStatus => {
console.log(rental["id"]); // This does return the id now!
if(rentalStatus == "Reserved") {
$("#assign-items").removeClass("d-none");
}
}).catch(error => {
console.log("Error:" + error);
});
error: Uncaught (in promise) TypeError: Cannot read property
'push' of undefined error line: " this.name[i].push(arrayData[0]);
"
I do not understand since the line before console.log("data is loaded:" + arrayData[0]); is working!
Is it something about async? Can someone please help me out?
Here is my code:
data: {
name: []
},
methods: {
LoadData: function() {
console.log("onload fundtion. \n");
fetch('http://localhost/store/skininfor.txt')
.then(response => response.text())
.then((data) => {
// console.log(data);
var textByLine = data.split("\n");
for (var i = 0; i < textByLine.length; i++) {
var arrayData = textByLine[i].split(",");
console.log("data is loaded:" + arrayData[0]);
if (arrayData[0] !== undefined) {
this.name[i].push(arrayData[0]);
}
}
});
},
By this way this.name[i].push(arrayData[0]); you are trying to push an element into another element this is why you have that error.
this.name is the tab and this.name[i] is one element so it should be this.name.push(arrayData[0]);
you don't have any element in the name array therefore you should push like this.
this.name.push(arrayData[0]);
You probably need to assign instead of pushing, i.e.
this.name[i] = arrayData[0];
(Although I can't be sure. If you defined example input data and desired output, that would be helpful).
Trying to fetch data from an API and add it to the DOM
Specifically, an array that contains objects.
Below is an example of what the API returns in the console.
I’m using a for loop and a for…in loop to access the array within the object
Code below
const getNews = document.getElementById('btn')
heyThere = () => {
axios.get('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=APIKEY')
.then(function (response) {
for (let i = 0; i <= response.data.articles.length; i++) {
for (key in response.data.articles[i]) {
ham.innerHTML = (response.data.articles)
}
}
console.log(response)
console.log(typeof response)
})
.catch(function (error) {
console.log(error);
})
}
getNews.addEventListener('click', heyThere)
The above code prints the following to the DOM
What’s the correct way to access the full list of articles(20 articles) and print them to the DOM?
You need to access the specific properties of response.data.articles[i] that you want to display, and create the desired HTML for each of them. Something like:
const getNews = document.getElementById('btn')
heyThere = () => {
axios.get('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=APIKEY')
.then(function(response) {
let html = '';
response.data.articles.each(article => {
html += '<div class="article">';
html += `<div class="author">${article.author}</div>`;
html += `<div class="description">${article.description}</div>`;
html += '</div>';
});
ham.innerHTML = html;
console.log(response)
console.log(typeof response)
})
.catch(function(error) {
console.log(error);
})
}
getNews.addEventListener('click', heyThere)
The solution below prints the articles to the DOM as a list.
heyThere = () => {
axios.get('https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=APIKEY')
.then(function (response) {
let news = response.data.articles
for (let i = 0, len = news.length; i < len; i++) {
console.log(news[i])
let li = document.createElement('li')
li.innerHTML = JSON.stringify(news[i].title)
document.querySelector('#ham').appendChild(li)
}
})
.catch(function (error) {
console.log(error);
})
}
getNews.addEventListener('click', heyThere)
Below are the articles printed to the page
Altering the response with dot notation allows one to return a list of URLs, authors, etc. For example, li.innerHTML = JSON.stringify(news[i].url)
Hope this is helpful!
I was learning react and doing some axios api call with an array. I did a code on gathering data through coinmarketcap api to learn.
So, my intention was to get the prices from the api with a hardcoded array of cryptocurrency ids and push them into an array of prices. But I ran into a problem with the prices array, as the prices were all jumbled up. I was supposed to get an array in this order
[bitcoinprice, ethereumprice, stellarprice, rippleprice]
but when I ran it in the browser, the prices came randomly and not in this order, sometimes I got my order, sometimes it didn't. I used a button which onClick called the getPrice method. Does anyone know what went wrong with my code? Thanks!
constructor(){
super();
this.state = {
cryptos:["bitcoin","ethereum","stellar","ripple"],
prices:[]
};
this.getPrice = this.getPrice.bind(this);
}
getPrice(){
const cryptos = this.state.cryptos;
console.log(cryptos);
for (var i = 0; i < cryptos.length; i++){
const cryptoUrl = 'https://api.coinmarketcap.com/v1/ticker/' + cryptos[i];
axios.get(cryptoUrl)
.then((response) => {
const data = response.data[0];
console.log(data.price_usd);
this.state.prices.push(data.price_usd);
console.log(this.state.prices);
})
.catch((error) => {
console.log(error);
});
}
}
If you want to receive the data in the order of the asynchronous calls you make, you can use Promise.all, that waits until all the promises of an array get executed and are resolved, returning the values in the order they were executed.
const cryptos = ['bitcoin', 'ethereum', 'stellar', 'ripple'];
const arr = [];
for (var i = 0; i < cryptos.length; i++){
const cryptoUrl = 'https://api.coinmarketcap.com/v1/ticker/' + cryptos[i];
arr.push(axios.get(cryptoUrl));
}
Promise.all(arr).then((response) =>
response.map(res => console.log(res.data[0].name, res.data[0].price_usd))
).catch((err) => console.log(err));
You could use a closure in the for loop to capture the value of i and use it as the index once the data is returned rather than using push:
getPrice(){
const cryptos = this.state.cryptos;
console.log(cryptos);
for (var i = 0; i < cryptos.length; i++) {
const cryptoUrl = 'https://api.coinmarketcap.com/v1/ticker/' + cryptos[i];
(function (x) {
axios.get(cryptoUrl)
.then((response) => {
const data = response.data[0];
console.log(data.price_usd);
var newPrices = this.state.prices;
newPrices[x] = data.price_usd;
this.setState({prices: newPrices});
console.log(this.state.prices);
})
.catch((error) => {
console.log(error);
});
})(i);
}
}
I have a block of code that push objects to a new Array from csv file using d3.csv().
I do not understand why console.log(data[0]) returns undefined.
This is my code:
let data = []
let csv = 'file.csv'
let read_csv = d3.csv(csv, (d) => {
d.map((i) => {
data.push(i)
})
})
console.log(data)
console.log(data[0])
First console returns all values as follow: Array(166). However, the second one returns undefined.
What am I doing wrong? Is this the proper way to select the array's index using this method?
Edit
I tried this code also:
var read_csv = d3.csv(csv, function (d) {
for (var i = 0; i < d.length; i++) {
data.push(d[i])
}
})
If I tried this:
let read_csv = d3.csv(csv, (d) => {
d.map((i) => {
console.log(i)
})
})
It returns each object, so I believe d3.csv() is reading data ok.