Skip to content Skip to sidebar Skip to footer

Sorting Data Fetched Asynchronously With Javascript Fetch Api

The following javascript function called runQuery was given to me by @Brad It gets data from a NodeJS server using the fetch API. It works great! It returns data from the server.

Solution 1:

Looks like you're not looking for any streaming. Just write

asyncfunctionrunQuery(queryExpression) {
    const res = awaitfetch('api/aUsers' + queryExpression);
    // Verify that we have some sort of 2xx response that we can useif (!res.ok) {
        console.log("Error trying to load the list of users: ");
        throw res;
    }
    // If no content, immediately resolve, don't try to parse JSONif (res.status === 204) {
        return [];
    }
    const content = await res.text();
    const lines = content.split("\n");
    return lines.map(line =>JSON.parse(line));
}

and then

const recordsArray = awaitrunQuery(document.querySelector(".queryExpressionTextArea").value);
recordsArray.sort(function(a, b) {
    return (a.email < b.email) - (a.email > b.email);
})
console.log(recordsArray); 

Solution 2:

I worked this solution with help from the webpage found here However I am selecting the answer from @Bergi as the solution because the code is shorter, more elegant, and because Bergi raises the point that waiting for the fetch to complete diminishes the benefit of using streams.

All the working code for this problem can be found at this link under the function: app.loadUsersListPage = async function(){Do stuff}

Notice the key word async above - That was necessary to make this work.

The action starts with a sub function of loadUsersListPage called onClickEventBehaviorOfSubmitQueryButton.

The following changes were made to that function in order to make this all work. Notice how it is different from the code in the original question.

// Run the query defined in the textarea on the form.let recordsArray = awaitrunQuery(document.querySelector(".queryExpressionTextArea").value)

    // Sort the recordsArray which was populated after running the query.
    recordsArray.sort(function(a, b)
    {
      //Sort by emailif (a.email > b.email) return -1;
      if (a.email < b.email) return1;
      if (a.email === b.email) return0;
    })

    console.log(recordsArray);

The code above calls the code below which was also changed to make it all work. Notice the use of the key words async and await throughout the function. Please also notice at the bottom of the function where code has been changed so that data is not returned to the sort function until all the data has been received from the server.

asyncfunctionrunQuery(queryExpression)
  {
    // Define a client function that calls for data from the server.//                    !!!const fetchPromise = awaitfetch('api/aUsers' + queryExpression)
    .then
    (
      (res) => 
      {
        // Verify that we have some sort of 2xx response that we can useif (!res.ok) 
        {
          // throw res;// Show the createCheck CTAdocument.getElementById("createNewRecordCTA").style.display = 'block';
          document.getElementById("createNewRecordCTA2").style.display = 'block';
          document.getElementById("createNewRecordCTA3").style.display = 'block';          

          console.log("Error trying to load the list of users: ");        
        }

        // If no content, immediately resolve, don't try to parse JSONif (res.status === 204) 
        {
          return;
        }

        // Initialize variable to hold chunks of data as they come across.let textBuffer = '';

        // Process the stream.return res.body// Decode as UTF-8 Text
        .pipeThrough
        (
          newTextDecoderStream()
        )

        // Split on lines
        .pipeThrough
        (
          newTransformStream
          (
            {
              transform(chunk, controller) 
              {
                textBuffer += chunk;            

                // Split the string of records on the new line character and store the result in an array named lines.const lines = textBuffer.split('\n');

                // Cycle through all elements in the array except for the last one which is only holding a new line character.for (const line of lines.slice(0, -1))
                {
                  // Put the element from the array into the controller que.
                  controller.enqueue(line);
                } // End of: for (const line ...)// Put the last element from the array (the new line character) into the textBuffer but don't put it in the que.
                textBuffer = lines.slice(-1)[0];             
              }, // End of: Transform(chunk, controller){do stuff}flush(controller) 
              {
                if (textBuffer) 
                {
                  controller.enqueue(textBuffer);
                } // End of: if (textBuffer)
              } // End of: flush(controller){do stuff}
            } // End of: parameters for new TransformStream
          ) // End of: call to constructor new TransformStream
        ) // End of: parameters for pipeThrough - Split on lines// Parse JSON objects
        .pipeThrough
        (
          newTransformStream
          (
            {
              transform(line, controller) 
              {
                if (line) 
                {
                  controller.enqueue
                  (
                    JSON.parse(line)
                  ); //End of: call to controller.enqueue function
                } // End of: if (line)
              } // End of: transform function
            } // End of: parameter object for new TransformStream
          ) // End of: new TransformStream parameters
        ); // End of: parameters for .pipeThrough - Parse JSON objects
      } // End of: .then callback function instruction for fetch
    ); // End of: .then callback parameters for fetch// Below the code has been changed so that data is not returned until the entire fetch has been completed.// Call to function which asks server for data.const res = await fetchPromise;

    const reader = res.getReader();

    let result = await reader.read();
    let fetchedArray = [];

    while (!result.done) {
      const value = result.value;
      fetchedArray.push(value);
      // get the next result
      result = await reader.read();
    }

    return fetchedArray;

  }; // End of: async function runQuery(queryExpression)

Thanks to all for helping me work through this. Clearly I need to study async/await and promises if I hope to accomplish my goals.

Post a Comment for "Sorting Data Fetched Asynchronously With Javascript Fetch Api"