0

I'm trying to change text in a div element to a string of text obtained from a json file when a button is clicked.

I'm reading from my json file declaring the information as data. I then wanted to run a function that is activated when buttons on my page are clicked to change the text to whatever index the button id corresponds to.

The json file just has an "events" array and each object has a "name" and "text". The name is irrelevant and is only there for me to distinguish what each one is really.

Each button in the html file has an individual id that starts from 1 and goes up for each button (there is no id 0 button because I have the first object in the array as a test in the json with nothing of value in it) and they also have an onclick event that triggers the changeText() function.

So my goal is to check the id of the button that is clicked and then get the "text" string from the json and change the innerHTML of the text-area div element into that.

This is the js code:

function loadData() {
    fetch('../text/events.json')
        .then(info => {
            return info.json();
        })
        .then(data => {
            console.log(data);
            return data;
        })
        .then(
            data => {
                var txt = document.getElementById("text-area");
                var btnID = this.id;

                txt.innerHTML = data.events[btnID].text;
            }
        )
}

Here is an example of one of the buttons I'm using: <button class="tl-btn btn-right" onclick="loadData()" id="2" style="margin-top: 10px">test1</button>

Here is the json file:

{
    "events": [
        {
            "name": "test-name",
            "text": "test-text"
        },
        {
            "name": "test-name1",
            "text": "test-text1"
        },
        {
            "name": "test-name2",
            "text": "test-text2"
        }
    ]
}

I keep getting: Uncaught TypeError: Cannot read property 'events' of undefined at changeText (main.js:18) at HTMLButtonElement.onclick (index.html:21)

I'm honestly not sure what the problem is. The json file reads perfectly since the console displays the logged data obtained from it.

I'm really sorry if I sound really confusing, please feel free to ask me anything that isn't clear and I look forward to any help.

Thank you! :D

EDIT 1: I changed some of the code based on the suggestions below and I'm now getting a different error: Uncaught (in promise) TypeError: Cannot read property 'text' of undefined

Edit 2: I found the problem with the code being that it couldn't read the format of the json so I just had to parse it like this:

.then(data => {
        var txt = document.getElementById("text-area");

        txt.innerHTML = JSON.stringify(data.events[0].text).slice(1,-1)
    })

The slice cleans up the quotation marks.

Mike Hanna
  • 18
  • 4
  • You don't need the parenthesis after `loadData` in this line `window.addEventListener('load', loadData())` - that will immediately invoke the function – Tom O. Jul 25 '19 at 19:22
  • Keep in mind that "fetch" goes after resources asynchronously, so you need to change the text and call changeText(data) only when you get a response back inside your "then". Because it is asynchronous, your code doesn't stop at that point to wait for something to be returned, like you did with "return data". – Elder Jul 25 '19 at 19:23
  • I've never heard of asynchronous calls before, I only used return because I was looking at other questions that were similar to mine before using return was suggested in the answer. I'll read up on the asynchronous calls though. Thank you! – Mike Hanna Jul 25 '19 at 19:31

1 Answers1

0

You need to move changeText into your callback with the data:

window.addEventListener('load', loadData);

function changeText(data) {
    var txt = document.getElementById("text-area");
    var btnID = this.id;

    txt.innerHTML = data.events[btnID].text;
}

function loadData() {
    fetch('../text/events.json')
        .then(info => {
            return info.json();
        })
        .then(data => {
            changeText(data);
            return data;
        })
}
Clarity
  • 10,730
  • 2
  • 25
  • 35