Get random element from json array

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);


There is a lot going on; but I’m assuming data is getting to the getRandomKanji function

let charss = data[Math.floor(Math.random() * data.length)]

Are you providing the API key when you make the request or have you deliberately redacted it in the code you posted? Because can’t currently test this.

But you aren’t returning the data in the functions, you’ve even commented to that effect:

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

So when you go onto the next then in the chain, you’re passing it undefined instead of the data, and you can’t map over undefined. To be explicit:

fetch(something)
  .then(data => {
    /* The value of `data` should be some JSON that came back
     * from `fetch` */
    return data.json();
    /* The return value is the result of parsing that JSON string
     * to a JS object */
  })
  .then(data => {
    /* the value of `data` is the return value of the last function
     * So `data` here is the value you've got from JSON.parse-ing the
     * response from your `fetch` call.
     */
    return console.log(data);
    /* the return value is undefined! */
  })
  .then(data => {
    /* the value of `data` here is the return value of the last function,
     * which was `undefined`, so `data` is `undefined`
     */
 ...

I simply don’t get where the data is then? And your code ECMA 6 then? I’m sometimes confused between the old way and the new way when analyzing codes.

I Tried this because I thought I needed a function to get all the second characters and a new function to go random through the kanji.

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": "f1fbf27c32mshce2a5ab13e928c9p155a0cjsn3eb8cd7f90a2"
	}
})


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[1].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;
//  }

const GetRandomKanji = (data) => {
	let chars = data.map(el => el.kanji.character + "<br>").join("");
	//[Math.random() * data.length | 2];
	console.log(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);


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

console.log(getJsonFromRes);
console.log(logData);

It’s a chain of functions. Take this data then do something to it then pass it to the next function then do something to it then pass it this the next function etc etc. Whatever the return value of the previous function is, that’s the input for the next one. If you return undefined from the previous function, that’s the input to the next one in the chain.

If you want to get some specific data from a function, return that specific data

I indeed want to return a single random element! But within the scope of the characters.
As my initial code returned all the kanji characters of the complete array. I want to random give only one of these with every refresh.

So I need to create the correct function that uses the former chain so the result isn’t undefined. Correct?
If so I thought that that was the case.

const logData = (data) => console.log(data[1].kanji.character);

My thought was I needed to put a variable ‘random’ instead of the [1] so it would be

const logData = (data) => console.log(data[random].kanji.character);