How to synchronize 'time-consuming value allotment' of a variable, with the next commands, in nodejs?

Viewed 63

The commands that we want to run in sync, are a part of app.post method in app.js:

ytQueryAppJs = httpsYtGetFunc(query);
console.log("ytQueryAppJs:");
console.log(ytQueryAppJs);
  • Here, httpsYtGetFunc is a time-consuming function and the array ytQueryAppJs gets logged in before httpsYtGetFunc finishes returning value. Hence, an empty array is logged.

  • Our aim is to log ytQueryAppJs, such that it contains the required values.

(I do not know how to categorise this question. Please suggest a title you find apt.)


Here is the complete code, shall it helps anyone understand the query better.

app.js

// This is a nodeJs-expressJs application.
const express = require("express");

// https to fetch data from end-point
const https = require("https");

// body-parser to read client's submitted queryValue
const bodyParser = require("body-parser");

// This app constant is created to be able to access the methods available in 'express' package.
const app = express();

// Starting the server
app.listen(3000, function() {
  console.log("Server is running on port 3000.")
});

// 'urlencoded' helps access html data. Other data formats could be JSON etc.
// body-parser required as to exclusively define "extended: true" although this is no use to us.
app.use(bodyParser.urlencoded({
  extended: true
}));

// ejs view engine has been used to use app.js variables into the output ejs file.
app.set('view engine', 'ejs');

// Variables to store the data fetched from API endpoint.
let i = 0;

let query = "";

let ytQueryResult = "";
let ytCoverResult = "";
let ytLiveResult = "";

let ytQueryAppJs = [];

let ytCoverAppJs = [];
let ytCoverUniqueAppJs = [];

let ytLiveAppJs = [];
let ytLiveUniqueAppJs = [];

// The page to load when the browser (client) makes request to GET something from the server on "/", i.e., from the homepage.
// This GET request is made as soon as the homepage url is entered in the address bar od browser, automatically.
app.get("/", function(req, res) {
  res.sendFile(__dirname + "/index.html");
});

// https://stackoverflow.com/a/14930567/14597561
function compareAndRemove(removeFromThis, compareToThis) {
  return (removeFromThis = removeFromThis.filter(val => !compareToThis.includes(val)));
}

// Declaring variables for the function 'httpsYtGetFunc'
let apiKey = "";
let urlOfYtGetFunc = "";
let resultOfYtGetFunc = "";
let extractedResultOfYtGetFunc = [];

// This function GETs data, parses it, pushes required values in an array.
function httpsYtGetFunc(queryOfYtGetFunc) {

  apiKey = "Az...xI"
  urlOfYtGetFunc = "https://www.googleapis.com/youtube/v3/search?key=" + apiKey + "&part=snippet&q=" + queryOfYtGetFunc + "&maxResults=4&order=relevance&type=video";

  // GETting data and storing it in chunks.
  https.get(urlOfYtGetFunc, (response) => {
    const chunks = []
    response.on('data', (d) => {
      chunks.push(d)
    })

    // Parsing the chunks to jJSON
    response.on('end', () => {
      resultOfYtGetFunc = JSON.parse((Buffer.concat(chunks).toString()))
      // console.log(resultOfYtGetFunc)

      // Extracting useful data, and allocating it.
      for (i = 0; i < (resultOfYtGetFunc.items).length; i++) {
        extractedResultOfYtGetFunc[i] = resultOfYtGetFunc.items[i].id.videoId;
      }
    })
  })
  return extractedResultOfYtGetFunc;
}

app.post("/", function(req, res) {

  // Accessing the queryValue user submitted in index.js
  query = req.body.queryValue;

  // Fetcing top results related to user's query and putting them in the array.
  ytQueryAppJs = httpsYtGetFunc(query);
  console.log("ytQueryAppJs:");
  console.log(ytQueryAppJs);

  // Fetching 'cover' songs related to user's query and putting them in the array.
  if (query.includes("cover") == true) {
    ytCoverAppJs = httpsYtGetFunc(query);
    console.log("ytCoverAppJs:");
    console.log(ytCoverAppJs);

    // Removing redundant values.
    ytCoverUniqueAppJs = compareAndRemove(ytCoverAppJs, ytQueryAppJs);
    console.log("ytCoverUniqueAppJs:");
    console.log(ytCoverUniqueAppJs);
  } else {
    ytCoverAppJs = httpsYtGetFunc(query + " cover");
    console.log("ytCoverAppJs:");
    console.log(ytCoverAppJs);

    // Removing redundant values.
    ytCoverUniqueAppJs = compareAndRemove(ytCoverAppJs, ytQueryAppJs);
    console.log("ytCoverUniqueAppJs:");
    console.log(ytCoverUniqueAppJs);
  }

  // Fetching 'live performances' related to user's query and putting them in the array.
  if (query.includes("Live") == true) {
    ytLiveAppJs = httpsYtGetFunc(query);
    console.log("ytLiveAppJs:");
    console.log(ytLiveAppJs);

    // Removing redundant values.
    ytLiveUniqueAppJs = compareAndRemove(ytLiveAppJs, ytQueryAppJs);
    ytLiveUniqueAppJs = compareAndRemove(ytLiveAppJs, ytCoverAppJs);
    console.log("ytLiveUniqueAppJs:");
    console.log(ytLiveUniqueAppJs);
  } else {
    ytLiveAppJs = httpsYtGetFunc(query + " live");
    console.log("ytLiveAppJs:");
    console.log(ytLiveAppJs);

    // Removing redundant values.
    ytLiveUniqueAppJs = compareAndRemove(ytLiveAppJs, ytQueryAppJs);
    ytLiveUniqueAppJs = compareAndRemove(ytLiveAppJs, ytCoverAppJs);
    console.log("ytLiveUniqueAppJs:");
    console.log(ytLiveUniqueAppJs);
  }

  // The 'results' named EJS file is rendered and fed in response. The 'required' data is passed into it using the following variable(s).
  // res.render("results", {
  //   ytQueryEjs: ytQueryAppJs,
  //   ytCoverUniqueEjs: ytCoverUniqueAppJs,
  //   ytLiveUniqueEjs: ytLiveUniqueAppJs
  // });
  // console.log("Value to be sent for rendering: ");
  // console.log(ytQueryAppJs);
  // console.log(ytCoverUniqueEjs);
  // console.log(ytLiveUniqueEjs);

  // Emptying all the arrays.
  ytQueryAppJs.length = 0;

  ytCoverAppJs.length = 0;
  ytCoverUniqueAppJs.length = 0;

  ytLiveAppJs.length = 0;
  ytLiveUniqueAppJs.length = 0;
});

index.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>One Music</title>
    <link rel="stylesheet" href="index.css">
  </head>
  <body onload="onPageLoad()">

    <div class="index-search-container">

      <!-- POST request to fetch data related to queryValue.  -->
      <form class="" action="/" method="post">
        <input id="queryId" type="text" name="queryValue" value="" placeholder="search">
        <button type="submit" name="button">HIT ME</button>
      </form>

    </div>

  </body>
</html>

Expected flow:

  • User submits query in index.html.
  • The values of arrays, ytQueryAppJs, ytCoverAppJs, ytCoverUniqueAppJs, ytLiveAppJs, ytLiveUniqueAppJs gets logged in the console, based on the query.

Current flow:

  • User submits query in index.js.
  • Aforementioned arrays get logged in console, but are empty.
  • User submits new query in index.html.
  • The values of arrays, ytQueryAppJs, ytCoverAppJs, ytLiveAppJs, gets logged in the console, based on the previous query.
  • These two arrays are also logged in but are still empty: ytCoverUniqueAppJs, ytLiveUniqueAppJs.

Note: I am a beginner. Shall the question requires better tags, please edit.

0 Answers
Related