0

I'm trying to use WordPress API with react, but it returns id instead of the tag name, so I'm trying to fetch the tag name with another API call. but it keeps returning undefined. When I add return before fetch inside getCategory() it just errors out.

componentDidMount() {
const URL =
  'https://public-api.wordpress.com/wp/v2/sites/sitename/posts/';

  fetch(URL)
  .then(res => res.json())
  .then(posts => {

    const post = posts.map(post => {
      return {
        ...post,
        categories: this.getCategory(...post.categories)
      };
    });

    this.setState({ posts: post });

    console.log(post);
  })
  .catch(err => console.log(err));
  }

  getCategory(id) {
   const URL = `https://public-api.wordpress.com/wp/v2/sites/sitename/categories/${id}`;

fetch(URL)
  .then(data => data.json())
  .then(res => res.name)
 }
4
  • A possible bug is that your getCategory expects a single id, but you are spreading all the post.categories there. Commented May 20, 2018 at 21:12
  • It's an array but with one value @LyoshaKorogoda Commented May 20, 2018 at 21:13
  • Ok so I commented out the setState and added return to fetch inside the getCategory() function now I return a promise for value categories, but when I call .then after this.getCategory(...post.categories) it's still a promise? Commented May 20, 2018 at 21:21
  • Mind you that getCategory has no return value, and even if you return the fetch, you are returning a Promise. Also, you might want to edit out your URLs Commented May 20, 2018 at 21:56

3 Answers 3

2

Basically, your problem is that you're setting the state before the fetch in getCategory resolves. To address that, you can await for its result --

componentDidMount() {
  const URL = 'https://public-api.wordpress.com/wp/v2/sites/sitename/posts/';  
  fetch(URL)
    .then(res => res.json())
    .then(posts => {
      return Promise.all(posts.map(async post => {
        return {
          ...post,
          categories: await this.getCategory(...post.categories)
        };
      }));
    })
    .then(posts => this.setState({ posts: posts }))
    .catch(err => console.log(err));
}

getCategory(id) {
  const URL = `https://public-api.wordpress.com/wp/v2/sites/sitenameress.com/categories/${id}`;

  return fetch(URL)
    .then(data => data.json())
    .then(res => res.name)
} 
Sign up to request clarification or add additional context in comments.

Comments

1

first: getCategory method returns nothing.

getCategory(id) {
   const URL = `https://public-api.wordpress.com/wp/v2/sites/sitename/categories/${id}`;

return fetch(URL).then(data => data.json()).then(res => res.name);

}

second: when you run setState method (probably) http request for category (getCategory) is still running, so categories are not set yet.

you should use Promise.all() method to be sure all http requests are done before you call setState method.

Comments

0

Referencing @lyosha-korogoda's answer, if you can't use async/await, try something like this instead:

componentDidMount() {
  const URL = 'https://public-api.wordpress.com/wp/v2/sites/<YOUR_WORDPRESS_URL>/posts/';

  fetch(URL)
    .then(res => res.json())
    .then(posts => {
      this.getCategory(...post.categories).then(category => {
        const post = posts.map(post => {
          return {
            ...post,
            categories: category
          };
        });
        this.setState({ posts: post });
        console.log(post);
      })
    })
    .catch(err => console.log(err));
}

getCategory(id) {
  const URL = `https://public-api.wordpress.com/wp/v2/sites/<YOUR_WORDPRESS_URL>/categories/${id}`;

  return fetch(URL)
    .then(data => data.json())
    .then(res => res.name)
}

Note how I moved getCategory out and wrapping the map into it's then block. Honestly the code could be cleaner, but just to show how it works.

As to why your fetch returns undefined, first it's because your getCategory(id) did not return anything. And second, it's simply because how JavaScript's asynchronous nature really, so your const post doesn't have value because getCategory(id) has not finished at that time.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.