Search code examples
javascriptfetchnuxt.jses6-promise

Fetching data with Nuxt


I'm calling data with Nuxt async fetch() like this:

export default {
....
  async fetch() {
    let childrenUrl = process.env.VUE_APP_MGNL_API_PAGES + this.projectPage + "/@nodes";
    await this.$http.$get(childrenUrl).then(childResult => {
      this.projectsPageChildren = childResult;
    })
  },

  fetchOnServer: false,
...
}

projectsPageChildren returns an array with objects, each containing a property "servicesMain" which contains an URL path, see screenshot below. enter image description here

I need to access the data of the servicesMain URL path and I'm assuming that to get it, I need to make another fetch call with the "servicesMain" URL.

So what I'm trying is this: I loop through the projectsPageChildren with v-for and on each child I call a function "getMainService" to which I pass the servicesMain URL.

    <div class="card" v-if="projectsPageChildren" v-for="project in projectsPageChildren">
      <div class="title">{{ getMainService(project.servicesMain) }}</div>
      <div class="title">{{ project.title }}</div>
      <Btn :to="project['@path']">More</Btn>
    </div>

The method "getMainService" is placed within VUE's "methods" hook and makes another asynchronous call with the URL that it receives as an argument.

  methods: {
async getMainService(servicePath) {
    let url = process.env.VUE_APP_MGNL_API_PAGES + servicePath;
    await fetch(url)
      .then(result => {
        result.json().then((data) => {
          console.log(data);
          console.log(data.title);
          return data.title;
        });
      })
      .catch(error => console.log(error));
},

},

The two console log statements in the function show the data that I need the function to return.

enter image description here

However, all I see in the browser is "[object Promise]". enter image description here

To summarise: I'm using Nuxt's fetch() hook to get my data which returns an array. Each object in the array contains an URL which points to more data.

How do set up this second fetch call properly? What am I missing here?

I read the docs on Nuxt data fetching and Javascript Promises and Responses, but none seemed to address my problem exactly.


Solution

  • I ended up soliving it like this:

    In my original code I as calling the method "getMainService()" in the Vue template section, which didn't work. Now I'm making a second request in the async fetch() method and call the method from there. In the forEach loop I'm basically rewriting the Objects' property to what the method returns.

    This is the new code:

      async fetch() {
    let thisPageUrl = process.env.VUE_APP_MGNL_API_PAGES + this.projectPage;
    await this.$http.$get(thisPageUrl).then(thisPageResult => {
      this.projectsPageData = thisPageResult;
    })
    
    let childrenUrl = process.env.VUE_APP_MGNL_API_PAGES + this.projectPage + "/@nodes";
    await this.$http.$get(childrenUrl).then(projectPages => {
      this.projectsPageChildren = projectPages;
      this.projectsPageChildren.forEach(projectPage => {
        this.getMainService(projectPage.extras[0].serviceMain).then(res => {
          projectPage.extras[0].serviceMain = res;
        });
      })
    
    })
    
    },
    
    fetchOnServer: false,
    

    The method getMainService() makes a call to a path and returns a string value:

      methods: {
     getMainService(servicePath) {
      let url = process.env.VUE_APP_MGNL_API_PAGES + servicePath;
      return this.$http.$get(url).then(serviceMain => {
        return serviceMain.title;
      })
    },
    

    },

    The template bit looks like this:

          <div>
        <div class="card" v-if="projectsPageChildren" v-for="(project, index) in projectsPageChildren">
          <div class="column_title">{{ project.serviceMain }}</div>
          <div class="title">{{ project.title }}</div>
          <Btn :to="project['@path']">More</Btn>
        </div>
      </div>
    

    Maybe not the prettiest solution, but it works. Thanks to @kissu and @GrafiCode, your comments nudged me in the right direction.