-1

I am trying to fetch the latest blog posts from Hubspot using their API and to do so I have to consume 2 endpoints (1 for the blog posts and 1 for the tag info for each blog post).

The first call brings back the latest blog posts. Then, for each blog post I need to retrieve the info for its tag, that the post has.

Below is the code that implements what described above,

  async getBlogs(contentGroupID: string = null, limit: number = null) {
    this.url = 'https://api.hubapi.com/cms/v3/blogs/posts?state=PUBLISHED&sort=-publish_date';

    const posts = await useFetch(
      this.url 
      + '&hapikey=' + this.HS_API_KEY
      + (contentGroupID ? '&content_group_id=' + contentGroupID : null)
      + (limit ? '&limit=' + limit : null)
    ).then(response => {
      return response;
    });

    const tags = (posts.data.value as any).results.map(post => fetch(`https://api.hubapi.com/blogs/v3/topics/${post.tagIds[0]+'?hapikey='+this.HS_API_KEY}`));
    const taggs = await Promise.all(tags);

    const payload = new Object();

    payload['blogPosts'] = posts;
    payload['tags'] = taggs;

    return payload;
  }

And here's the response at the Browser

enter image description here

As shown in screenshot above, the blogPosts object has been resolved just fine but the Promise.all() part to retrieve the tagIds[0] hasn't. It returns [object Response].

I have tried several different ways to do this and each one is always returning the Promise object unresolved. What is the correct way to do this and get the actual data?

Just to give an example of what the tag data object looks like, for the tag with id 41520763199 its data is as shown below. This is what I should be getting as a response instead of the promise object.

{
    "categoryId": 3,
    "contentIds": [],
    "created": 1613125431347,
    "deletedAt": 0,
    "description": "",
    "id": 41520763199,
    "language": "en-us",
    "name": "Case Studies",
    "portalId": 2734675,
    "slug": "case-studies",
    "translations": {},
    "updated": 1616091635999
}
Smolikas
  • 326
  • 1
  • 6
  • 19
  • Fetch returns a Response object which you then have to resolve by using e.g. `await fetch(...).then(r => r.json())`, you have to await this too because `.json()` (or others) will also return a promise. – MrCodingB Feb 13 '22 at 16:38
  • @MrCodingB Thank you but this is something I already know and doesn't answer my question. How would I solve my problem? May you have something more to suggest? As you already see in my code, I am already using `await` for `Promise.all()`. – Smolikas Feb 13 '22 at 16:40
  • I'll write it in my answer. It's too long for a comment – MrCodingB Feb 13 '22 at 16:40

2 Answers2

2

It's not returning a promise. The promise is resolved to a Response object as per this fetchAPI resource

One of the methods that you will find useful is Response.json that returns a promise that resolves with the result of parsing the response body text as JSON

As an example:

const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')

will result in response being a Response object.

 Response {type: 'basic', url: 'https://jsonplaceholder.typicode.com/todos/1', redirected: false, status: 200, ok: true, …}

Now calling:

const json = await response.json()

Will result in json being your actual response:

{userId: 1, id: 1, title: 'delectus aut autem', completed: false}
cogitovirus
  • 705
  • 6
  • 11
1

fetch will return a Promise<Response>, to actually get the result as a js object from a json string, you'd have to call .json() on the response object. You can do this within a .then callback, to not have to write two awaits.

async getBlogs(contentGroupID: string = null, limit: number = null) {
    this.url = 'https://api.hubapi.com/cms/v3/blogs/posts?state=PUBLISHED&sort=-publish_date';

    const blogPosts = await useFetch(
      this.url 
      + '&hapikey=' + this.HS_API_KEY
      + (contentGroupID ? '&content_group_id=' + contentGroupID : '')
      + (limit ? '&limit=' + limit : '')
    );

    const tagPromises = (posts.data.value as any).results
        .map(post => fetch(`https://api.hubapi.com/blogs/v3/topics/${post.tagIds[0]+'?hapikey='+this.HS_API_KEY}`)
            .then(r => r.json()));

    const tags = await Promise.all(tagPromises);

    return {
        blogPosts,
        tags
    };
}
MrCodingB
  • 2,284
  • 1
  • 9
  • 22
  • 1
    Oh dear.. I was trying to `.then()` on `const tags = await Promise.all(tagPromises).then(r => r.json()));` all this time and I was always getting object reponse. I never tried `.then()` on `const tagPromises()`. Thank you! – Smolikas Feb 13 '22 at 16:52