0

I do apologise in advance for what seems like a stupid question that has been answered so many times before, however I just can't get my head around exactly how to accomplish what I'm trying to do and I've been going round and around in circles for hours now re-writing the same bit of code over and over again.

I am very much a beginner at any kind of programming (bar some SQL wrangling and a bit of dodgy VBA stuff) and find it difficult to learn without a specific problem I want to solve. I have done some basic javascript course stuff so I know the basic syntax.

What I am trying to do is make a GET request using axios to get some data from an api and use the data it responds with to set the value of a variable that I'm then using to display on the screen.

Essentially what I want to do is this (within a nodejs .js script):

  • Get data from a GET api call
  • Get a value from that data to make a second GET API call
  • Use the data from that second call to place into variables that I can use within a function

At the moment I'm stuck at the first hurdle, this is what I have so far (that works):

const queryData = '123456';

const getLink = async () => {
  try {
    const resp = await axios.get(`https://www.apisite.com/${queryData}`);
    return resp.data;
  } catch (err) {
    console.error(err);
  }
};

getLink().then(console.log);

And this does actually do something, the console is populated with the object returned by the API

Where I am stumped is how to get that data into my variable to use on screen. Essentially what I want to do here is

let myObject = getLink();

From there I would then want to use the rest of the object so I could have:

let title = myObject.title;
let desc = myObject.description;
let user = myObject.user;

etc.

And this is where I am stuck because I can't seem to find a way to "get the data out" so to speak. I've tried suggestions about adding a new async function, about wrapping it as an IIFE and I just can't figure out what the answer is.

Any help at all (using as basic a concept as possible) would be much appreciated here.

@Bergi - the function I'm trying to call this is here. However I haven't actually been using this function to test, I've just been doing it from an empty project to just see if I can get the basics to work so I don't have to worry about other things obfuscating the issue. I'm trying to test it outside of any function at the moment just trying to see exactly how to get the data out to implement it. The below is the fabricated version of what I would be trying if I could get this to work but it is likely it is full of errors because I haven't actually tried to run this, I made it purely to show what I'm trying to do:

testing = function(tokens, idx, options, env, self) {
  const token = tokens[idx];
  if (token.info !== 'isbn') return defaultRender(tokens, idx, options, env, self); //checks for 'isbn' code fence token

  const elementId = 'isbn_target_' + Math.random() + '_' + Date.now();
  const element = document.createElement('div');

  let html = '';

  try {
    element.setAttribute('id', elementId);
    element.style.display = 'none';
    document.body.appendChild(element);

    //let queryData = token.content.trim(); 

    const queryData = '123456';

    const getLink = async () => {
      try {
        const resp = await axios.get(`https://www.apisite.com/${queryData}`);
        return resp.data;
    } catch (err) {
      console.error(err);
    }
  };

  let queryResponse = getLink();
  let title = queryResponse.title;

    html = '<div style="background-color: white;">' + title + '</div>';
  } catch (error) {
    console.error(error);
    return '<div style="border: 1px solid red; padding: 10px;">Could not render preview: ' + htmlentities(error.message) + '</div>';
  } finally {
    document.body.removeChild(element);
  }

  return html;
};
  • 2
    Your function is asynchronous; just `await` the result of `getLink();`, a la `let myObject = await getLink();` – esqew Nov 10 '21 at 18:24
  • So that is something I did try but I thought that you couldn't use `await` like that outside of an async function. If I try that I get: `SyntaxError: await is only valid in async functions and the top level bodies of modules` – rate_empty Nov 10 '21 at 18:31
  • You must be running an outdated version of Node - as of v14.18.0 top-level `await`s are in fact allowed. However you can just wrap your code in an anonymous `async` function if you can't/don't want to upgrade for whatever reason - refer to [my answer on another thread earlier today](https://stackoverflow.com/a/69912892/269970) to see how you might do that. – esqew Nov 10 '21 at 18:40
  • I'm apparently on v16: ```sh $ node -v v16.8.0 $ npm -v 7.24.0 $ node app.js /home/me/thing/app.js:31 let myObject = await getLink(); ^^^^^ SyntaxError: await is only valid in async functions and the top level bodies of modules... ``` I tried the anonymous async function thing before (in a number of different guises) and I can't wrap my head around exactly what it is doing. If I try the following I simply don't get anything, I suspect I'm missing something fundamental as nothing gets returned: ```js (async () => { let myObject = await getLink(); })(); ``` – rate_empty Nov 10 '21 at 18:53
  • Please post the whole code of the function where you do `let myObject = getLink();`. – Bergi Nov 10 '21 at 19:18

1 Answers1

1

Because getLink() is async, it returns a Promise.

In Node v14.18.0 and later, you can simply await it:

let myObject = await getLink();

You can wrap your code in an anonymous async function if you're running a prior version of Node:

(async () => {
    let myObject = await getLink();
    let title = myObject.title;
    let desc = myObject.description;
    let user = myObject.user;
})();

While outside the scope of the question as you've asked it here, you might also consider decreasing the verbosity of your code by using Destructuring assignment to assign your values:

let myObject = await getLink();
let {title, 'description': desc, user} = myObject;
esqew
  • 42,425
  • 27
  • 92
  • 132
  • Running `node -v` implies I'm using v16.8.0 but it doesn't allow me to do that. One of the issues I don't understand is how to actually use the data when it is wrapped in an anonymous function like that, it just doesn't return anything or I don't understand how to make it return the data (or I don't know how to make it execute). As for the de structuring, thank you but that will definitely come later, this is just me trying to get the very basics to work so basically nothing here is how I'll actually be using the response data, this was just to see if I can assign them at all. – rate_empty Nov 11 '21 at 09:21