How to extract value from an array of multiple JSON urls?

Hi, I’m trying to write a sketch that replaces all the nouns in the user input content with the dictionary definition of the noun.

I’m using RiTa.js to detect the nouns (that part is successful), and Wordnik API for the definitions.
For each noun detected, I created a url that links to the Wordnik JSON file in relation to the noun, and I put all the nouns in nounArray, all the urls in urlArray–both of which print correctly in the console so far.

Now the question is: how can I extract the [1].text value in each of the JSON files, and put them into the definitionArray?
An example of the Wordnik JSON file:

Here’s my dysfunctional code which won’t print the definitionArray:
This line needs to be added into the index.html part:

<script src="https://unpkg.com/rita@2.8.31/dist/rita.js"></script>

Then in the sketch:

var input;
var button;
var api1 = 'https://api.wordnik.com/v4/word.json/';
var api2 = '/definitions?limit=200&includeRelated=true&useCanonical=false&includeTags=false&api_key=wmw2c7bi8zih4peeugrgr595b02vem2h1y5jkvm29ghohhpuk';
var dictionary;
let nounArray = []
let urlArray = []
let definitionArray = []

function setup() {
    opts = {
        ignoreCase: true,
        ignoreStopWords: true
    };
    noCanvas;
    input = createInput("There is a tree in front of my house");
    button = createButton("submit");
    input.changed(processRita);
    button.mousePressed(processRita);
    input.size(300);
}

function processRita() {
    var s = input.value();
    var words = RiTa.tokens(s);
    var pos = RiTa.pos(s);
    console.log(words);
    console.log(pos);

    var output = '';

    for (var i = 0; i < words.length; i++) {
        if (/nn.*/.test(pos[i])) {
            nounArray.push(words[i]);
            urlArray.push(api1 + words[i] + api2);
            console.log('nouns: ', nounArray);
            console.log('urls: ', urlArray);
            // up until this point, nounArray and urlArray print out correctly

            definitionArray = [];
            getDefinition();

            function getDefinition() {
                for (var i = 0; i < urlArray.length; i++) {
                    loadJSON(urlArray[i], gotData);
                }
            }

            function gotData(data) {
                definitionArray.push(data[1].text);
            }
            console.log('definitions: ', definitionArray);

            output += definitionArray[i];
        } else {
            output += words[i];
        }
        output += " ";
    }
    createP(output);
}
1 Like
  function getDefinition() {

and

  function gotData(data) {

are INSIDE of function processRita () {

is this intentional?


Remark 1

(related)

use menu Edit | Tidy to get better indents that show you this

(I don’t know the language, so it’s just a remark, maybe it’s valid to place a function inside a function)


Remark 2

I can’t run your code, it says Rita is not defined.


Remark 3

from your screenshot (which is too short) you can maybe use the ID and modify it to get from the text JSON object (the first section) to the 2nd section

OR when it’s just an array, go to next element and retrieve text from there?

to get real help please post your screenshot as text and longer

1 Like

Your posted sketch code is lacking proper indentation.

You can use a code “beautifier” like this 1:
https://Beautifier.io

This is JSON array for “tree”:

[
  {
    "id": "T5367300-1",
    "partOfSpeech": "noun",
    "attributionText": "from The American Heritage® Dictionary of the English Language, 5th Edition.",
    "sourceDictionary": "ahd-5",
    "sequence": "1",
    "score": 0,
    "word": "tree",
    "attributionUrl": "https://ahdictionary.com/",
    "wordnikUrl": "https://www.wordnik.com/words/tree",
    "citations": [],
    "exampleUses": [],
    "labels": [],
    "notes": [],
    "relatedWords": [],
    "textProns": []
  },
  {
    "id": "T5367300-2",
    "partOfSpeech": "noun",
    "attributionText": "from The American Heritage® Dictionary of the English Language, 5th Edition.",
    "sourceDictionary": "ahd-5",
    "text": "A perennial woody plant having a main trunk and usually a distinct crown.",
    "sequence": "2",
    "score": 0,
    "word": "tree",
    "attributionUrl": "https://ahdictionary.com/",
    "wordnikUrl": "https://www.wordnik.com/words/tree",
    "citations": [],
    "exampleUses": [],
    "labels": [],
    "notes": [],
    "relatedWords": [],
    "textProns": []
  }
]
1 Like

Hi, thanks for the reply.
This line needs to be added into the index.html part:

<script src="https://unpkg.com/rita@2.8.31/dist/rita.js"></script>

I have a sketch that does work with the Wordnik API & RiTa.js:

The function gotData(data) is inside the function processRita and it works so maybe we can ignore that for now.
The problem with the initial sketch is that it only recognizes one definition, so I created the second sketch adding some arrays in case there are multiple nouns, which is the content in my original post.
and here is the full sketch, the complete JSON file can be found in the urls printed in the console:

1 Like

Thanks, I updated the code with https://beautifier.io
I use a JSON formatter on Chrome.

1 Like

doesn’t work for me, says dict undefined

or do you have another version?

1 Like

Yeah the second link would say undefined, and not printing out anything in the definitionArray–which is the one I’m asking for help on.
The first link works if there’s only one noun (might need to click the button more than once)
I’m posting the first link again here:

Just <script src=https://Unpkg.com/rita></script> is enough for grabbing library RiTa.js.

The last statement output += definitionArray[i]; is attempting to read from array definitionArray[] before it’s fully populated by loadJSON() + gotData()!

We should never immediately access data that’s asynchronously acquired.

Hmmm the reason I didn’t write loadJSON() in the preload was that before there are urls in the urlArray, there’s no link to JSON files to be loaded, and all of those are determined by the nouns in the content that would be changing in real time depending on user input :thinking:

@GoToLoop How can we wait until it’s loaded?

At OP: try to fix and clean up your 1st code so that it works with
multiple words and on the first mouse click

1 Like

:joy: The 2nd sketch was my attempt to fix the 1st one, by putting everything in arrays in case there are multiple of them, and I’m stuck at not being able to extract all the [1].text in those JSON files.

1 Like

Maybe repair the 1st and stick to one definition

And please no function within function

This is my attempt for your sketch:

Basically I’ve declared a global variable loads, which keeps the current number of active loadJSON().

When loads is decreased back to 0, via callback decreaseCounter(), function generateOutput() is called back.