Iterate thru json fetch

Hi I’m learning javascript.

And I’m trying to iterate thru a json file with js fetch.

I am first retrieving the whole file which I would then use to go through the list and get
randomly every nth result from a random object.

UPDATE:

I’ve managed to console log an element of the json list.

I’m still searching a good way to push the element to a div
And
When onload of the body a new element is presented.

Current code:

var myfetch = fetch("https://kanjialive-api.p.rapidapi.com/api/public/kanji/all", {
	"method": "GET",
	"headers": {
		"x-rapidapi-host": "kanjialive-api.p.rapidapi.com",
		"x-rapidapi-key": "x"
	}
})

myfetch
.then((res) => res.json())
.then((data) => console.log(data[1].kanji.character))
.then((data) =>  
    document.getElementById('kanji').innerHTML = kanji.character)


.catch(err => {
	console.log(err);
});

I get undefined in my html now!

Hello!

Could You share the code?

I would suggest reading the docs on the fetch api. Specifically
MDN: Fetch
MDN: Response
MDN: Body.json()

It looks like you’ve already got a handle on Promises (hopefully!); with that and the above knowledge you should have the tools to get your response into standard js types and work with it from there. :grinning:

1 Like

So I did this:


var myfetch = fetch("https://kanjialive-api.p.rapidapi.com/api/public/kanji/all", {
	"method": "GET",
	"headers": {
		"x-rapidapi-host": "kanjialive-api.p.rapidapi.com",
		"x-rapidapi-key": "x"
	}
})

myfetch
.then((res) => res.json())
.then((data) => console.log(data[1].kanji.character))
.then((data) =>  
    document.getElementById('kanji').innerHTML = kanji.character)


.catch(err => {
	console.log(err);
});

And now I see undefined on my html page.
Where do I need to look into to get this pushing of data on to html.

The first line in my quote references the kanji property of the data array. data[1].kanji.character
The second line references a kanji.character variable that you haven’t defined anywhere - thus the undefined you see on your page.
In this second step, the variable you use and the name you’ve given it in the arrow function would need to match.

But I thought the data was the variable output of the json resp the line above that.

Is there a link to description about this? I’ve tried fetch from api to div etc…
And also numerous stackoverflow pages. But they are different (in my eyes ofcourse ):smile: from what I have or want to achieve.

I’m pretty sure this example says it but I can’t muster the same result.

fetch('products.json').then(function(response) {
  return response.json();
}).then(function(json) {
  products = json;
  initialize();
}).catch(function(err) {
  console.log('Fetch problem: ' + err.message);
});

When you return the above, the returned value is undefined. That is because console.log statements have undefined as a return value. In the second then (shown below), kanji.character does not mean anything by itself. You can delete the line with the console.log and then reference data like you did in the console.log, but assign the kanji.character of the 2nd element of data to innerHTML.

data in your callback functions does contain the return value of the previous step in the chain.
But document.getElementById('kanji').innerHTML = kanji.character doesn’t reference the named parameter data. It tries to set the element’s innerHTML to kanji.character, a variable you haven’t defined.

It might be easier to picture if you extract your callbacks to their own functions. So from this:

to this

/** Parse response object
 * returns object parsed from json
 */
const getJsonFromRes = (res) => res.json();

/**  Logs some data. 
 * returns undefined
 */
const logData = (data) => console.log(data[1].kanji.character);

/** Ignores its data parameter. Attempts to set an element to an uninitialized variable.
 */
const accessMagicVariable = (data) => document.getElementById('kanji').innerHTML = kanji.character;

// print error to console. returns undefined.
const logError = (err) => console.log(err);

myfetch 
  .then(getJsonFromRes) 
  .then(logData) 
  .then(accessMagicVariable) 
  .catch(logError);

Then look at each function individually. The humorously (I hope) named accessMagicVariable is the problem I’m referring to. The blander logData is the problem RandellDawson has noted. logData needs to be rewritten to return the value you’d like to work with in the next part of the chain. accessMagicVariable needs to be rewritten so that it’s statements refer to the actual parameter name the function is receiving.

Hopefully that helps a tiny bit?

*note: my statements about kanji.character being defined in accessMagicVariable are based on the code you’ve provided. If there’s more code in scope at this point that you haven’t shown, I would have no way of knowing that.

Edit: There’s also a handy debugger command you can insert into your code when running in a browser. It will let you step through execution and see the value of variables that are in scope and all sorts of useful things like that. I’m struggling to maintain consciousness, otherwise i’d find a link for you. Sorry

@RandellDawson Thanks I figured it out with you response!

@partylich Your code looks much cleaner and structured than mine. now I can start make variables for the other api data and make loops. And then make it faster :slight_smile: much to do!! Thanks again!

I have a new wall I’m against.

I thought I got how it worked for running thru an array and giving a random element. But the code gives me an error in console:

TypeError: Cannot read property 'length' of undefined
    at getRandomKanji (kanjitab.js:40)

This is the code I’m trying to recreate the commented part of the code but for my json array.

var myfetch = fetch("https://kanjialive-api.p.rapidapi.com/api/public/kanji/all", {
	"method": "GET",
	"headers": {
		"x-rapidapi-host": "",
		"x-rapidapi-key": ""
	}
})


var i, x = "";

/** Parse response object
 * returns object parsed from json
 */
const getJsonFromRes = (res) => res.json();


 
/**  Logs some data. 
 * returns undefined
 */
const logData = (data) => console.log(data[2].kanji.character);

/** Ignores its data parameter. Attempts to set an element to an uninitialized variable.
 */
//const accessKanji = (data) => {
//	let chars = data.map(el => el.kanji.character + "<br>").join("");
//	document.getElementById('kanji').innerHTML = chars;
//  }

console.log(x)
// print error to console. returns undefined.
const logError = (err) => console.log(err);

// Example comment for what I want to achieve
  //var myArray = ['January', 'February', 'March']; 
  //var rand = myArray[Math.floor(Math.random() * myArray.length)];
	//console.log(rand);
const getRandomKanji = (data) => {
	let charss = getRandomKanji([Math.floor(Math.random() * data.length)]);
	console.log(charss);
}

myfetch 
  .then(getJsonFromRes) 
  .then(logData) 
  .then(getRandomKanji)
  //.then(accessKanji) 
  .catch(logError);