christo
christo

Reputation: 489

Typescript: how to structure a fetch API call inside a method that returns a Promise response

Maybe a trivial one, but I am new with Typescript and fetch API. In an exported class I have a public method remoteFetchSomething like:

export class className {
  remoteFetchSomething = (url : string) : Promise<Response> => {
    return fetch(url)
      .then(
        (r) => r.json()
      )
      .catch((e) => {
        console.log("API errore fetching " + objectType);
      });
  }
}

export const classInstance = new className();

The method queries a remote JSON API service, and in the code, I am using it like:

import { classInstance } from ...

classInstance.remoteFetchSomething('https://example.url')
  .then((json) => {
    console.log(json);
  }
)

The console.log is actually showing the results, but the remoteFetchSomething returns a Promise and I am unable to parse and access the JSON object values.

I would like to wait for the response before executing the remaining code, but how do I unwrap content from promise? Should I again put another .then? What am I missing?

Thank you.

Upvotes: 0

Views: 12804

Answers (3)

Jar
Jar

Reputation: 2010

this is how I do it:

type Payload = {
    id: number
}

type ReturnType = number

export const functionThatHasNumberType = async (
    payload: Payload
): Promise<ReturnType> => {
    let url = `/api/${payload.id}`

    return await axios.get(url)
}

Upvotes: 0

christo
christo

Reputation: 489

By now I resolved the problem defining the return type of the remoteFetch as any:

remoteFetchSomething = (url : string) : any => {
return fetch(url)
  .then(
    (r) => r.json()
  )
  .catch((e) => {
    console.log("API errore fetching " + objectType);
  });
}

And now I can access JSON values like data below:

classInstance.remoteFetchSomething('https://example.url').then(
  (json) => {
    console.dump(json.data);
  }
)

[sincerely still not clear why I cant' use the Promise<Response> type]

Upvotes: 2

caesay
caesay

Reputation: 17213

You can't synchronously block while waiting for a request in javascript, it would lock up the user's interface!

In regular javascript, and most versions of TypeScript, you should be / must be returning a promise.

function doRequestNormal(): Promise<any> {
    return fetch(...).then(...);
}

function someOtherMethodNormal() {
    // do some code here
    doRequestNormal.then(() => {
        // continue your execution here after the request
    });
}

In newer versions of typescript, there's async/await keyword support - so instead it might look like this:

async function doRequestAsync() {
    var result = await fetch(...);
    // do something with request;
    return result;
}

async function someOtherMethodAsync() {
    // do some code here
    var json = await doRequestAsync();
    // continue some code here
}

Keep in mind, doRequestAsync still returns a Promise under the hood - but when you call it, you can use await to pretend that you're blocking on it instead of needing to use the .then( callback. If you call an async method from a non-async method, you'll still need to use the callbacks as normal.

Upvotes: 1

Related Questions