Typescript - Promise resolves prematurely

I have been given a code with three essential parts that cannot be altered:

1. First, there is a call to the getData function, followed by printing the output.

getData().then(console.log); 

2. The function signature is as follows:

async getData(): Promise<string[]>

3. There is also the getDataFromUrl function:

function getDataFromUrl(url: string, callback: any) {
   fetch(URL)
   .then((content: any) => content.json())
   .then((data) => callback(data));
}

Below is my implementation for the getData function:

async getData(): Promise<string[]> {  
  return await new Promise<any>(function(resolve, reject) {
    resolve(getDataFromUrl(myUrl, ((data: string[]): string[]=> { 
      return data
    })))
  }); 
} 

The issue I am facing is that the code after the fetch function is executed after:

getData().then(console.log);

Therefore, console.log ends up printing: undefined

What modifications do I need to make in the getData function to resolve this?

Thank you

Answer №1

Instead of completing the getDataFromUrl function, focus on completing the value that the callback function reveals.

getData(): Promise<string[]> {  
  return new Promise<string[]>(function(resolve, reject) {
    getDataFromUrl(myUrl, (data: string[]): string[] => { 
      resolve(data)
    })
  }); 
} 

It's a shame you can't modify the other functions, because utilizing the promise created by fetch in your getDataFromUrl function would significantly improve the code, as shown by Quentin.

Answer №2

The function getDataFromUrl does not have a return value, so it will result in undefined.

Therefore, when you pass undefined to resolve (which resolves another promise), the promise created later by getDataFromUrl (or specifically fetch) resolves.


  • Avoid creating additional promises unnecessarily.
  • Avoid mixing callbacks and promises.

Simply return the promise from fetch.

function getDataFromUrl(url: string, callback: any) {
   return fetch(URL)
   .then((content: any) => content.json());
}

Then, utilize that promise instead of creating a new one in getData (which does not require the use of await as it will just resolve the promise which will immediately be wrapped in a new promise by async).

getData(): Promise<string[]> {  
    return getDataFromUrl(myUrl);
}

Answer №3

function fetchAndDisplayData(url, callback) {
  // Utilizing fetch (which returns a promise) and then chaining to pass data to the callback function.
  fetch(url).then((response) => response.json()).then(data => callback(data));
}

// Edit: No need for async anymore.
function getDataFromAPI() {
  // Creating a promise...
  return new Promise((resolve, reject) => {
    // Using arrow function to call the API and resolve the data.
    fetchAndDisplayData('https://randomuser.me/api/', (data) => resolve(data));
  })
}

// Displaying the fetched data once getDataFromAPI completes.
getDataFromAPI().then(data => console.log(data));

References:

  • Fetch API
  • Async, Await, and Promise
  • Callback Functions

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What steps can I take to avoid random divs from overlapping on smaller screens when dealing with elements created in the created() hook?

I encountered an issue with the code I'm working on (the circles overlap in the fiddle provided, but display correctly on my PC - possibly due to pixel discrepancies in the fiddle). You can find the code here. TestCircle.vue: <template> <d ...

Update button Image upon click

Is there a way to swap the image on a button when it's clicked? I want my button to start with one icon, but then change to another icon once it has been clicked. How can I achieve this effect? Any suggestions on how to make this happen? Check out ...

Spontaneous visual paired with text upon refreshing

I am new to Java script and I am working on creating a web page that displays two random numbers every time it is refreshed. Depending on these numbers, specific text should be shown. These numbers are represented by images ranging from 0 to 5. Currently ...

Preload-webpack-plugin does not support pre-fetching files

I have a query about prefetching and preloading content. In my vue app, I noticed that after building, I have duplicate files loaded in my dist/index.html file. Here is an example: Additionally, the "scripts" are not being preloaded/prefetched as expec ...

Uninstall webpack-dev-server version 1.14.1 and replace it with version 1.14.0

Can someone help me with the process of uninstalling webpack-dev-server 1.14.1 and installing version 1.14.0 on Ubuntu using just commands? Error message: Uncaught TypeError: Cannot read property 'replace' of null at eval (eval at globalEval (jq ...

Changing color of entire SVG image: a step-by-step guide

Check out this SVG image I found: https://jsfiddle.net/hey0qvgk/3/ <?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg version="1.1" width="90" height="9 ...

Cookie-powered JavaScript timer ceases after 60 seconds

I'm having an issue with my countdown timer where it stops counting after just one minute. It seems to pause at 54:00 when I set it for 55 minutes, and at 1:00 when I set it for 2 minutes. Any suggestions on how I can resolve this and make it continue ...

Executing JavaScript functions from an ASP.NET Razor view is achieved by using the

While working on a view in which I am writing Razor code, I encountered the need to call a JavaScript function with the JSON generated by the Razor code: // JavaScript function function buildTemplate(currentTemplate) { alert('hello world'); } ...

Retrieving latitude and longitude data for airports from Airports.JSON using React Native

I am encountering an issue while trying to query data from a JSON file that I have imported. You can access the file here import * as airportData from '../../Data/airports.json'; Initially, I successfully extracted the latitude value from the fi ...

Tips for retrieving the text from a POST request in C#

I have a basic Angular form that allows users to upload a file along with a description. constructor(private http: HttpClient) { } upload(files) { if (files.length === 0) return; const formData: FormData = new FormData(); var filedesc ...

Is there a way to unselect a button in Angular?

I have a set of buttons representing different categories. When I click on a button, it displays a card with relevant information. <app-category-button [label]='category.name' [isSelected]='category.id === (selectedCategoryId$ | asy ...

Deleting a file from the assets folder in Angular for good

I am attempting to permanently delete a JSON file from the assets folder using my component. Despite trying to use HttpClient, I encounter no errors but the file remains undeleted. constructor(http: HttpClient){} remove() { this.http.delete('assets ...

Implementing color with JavaScript by utilizing RGB input boxes

I am currently working on a project where I am attempting to change the color of a text area based on RGB values entered into input boxes. However, I am facing some challenges getting the values to apply correctly. Below is the code snippet I am working wi ...

What could be the reason for the individual components not being populated within the listItem?

*** I am iterating through an array and calling the ListItem component for each item. However, only one ListItem is being populated when there should be 3. Can someone please help me figure out what's wrong? *** Here is my code in App.js *** import F ...

Introducing a detailed model showcasing information sourced from an array of objects within Angular 14

I'm struggling to showcase detailed models for various elements in my project. In essence, I have a collection of cards that hold diverse information data. The objective is simple: upon clicking a button to reveal more details about a selected card, a ...

Getting just the main nodes from Firebase using Angularfire

I'm having trouble figuring out how to print just the parent element names from the structure of my database. The image provided shows the layout, but I can't seem to isolate the parent elements successfully. ...

Exploring Angular 4.3's HTTP Interceptor Retry功能

As I delve into my first attempt at coding, I find myself faced with the challenge of capturing 401 errors using HttpInterceptor. My goal is to generate a new auth token based on a certain condition and then retry the process with that token in place. Howe ...

Can you explain the meanings of <div class="masthead pdng-stn1"> and <div class="phone-box wrap push" id="home"> in more detail?

While working on styling my web pages with CSS and Bootstrap, I came across a few classes like "masthead pdng-stn1" and "phone-box" in the code. Despite searching through the bootstrap.css file and all other CSS files in my folders, I couldn't find a ...

Difficulty transmitting Heroku environment variable to Angular CLI application using Node.js

Currently, I am tackling a project that requires passing a stripe key as JSON within Angular. I've stored the key in Heroku config vars and have been attempting to pass that value through the Node.js backend to Angular using the process.env.STRIPE_KE ...

creating dynamic column headers with JavaScript

I am looking for a way to make the column names dynamic so that I don't have to manually update them every time. Here is my code snippet: jqGrid11.prototype = { display : function() { $('body').append(this.html.join("")); $("#jqGrid").j ...