'await' has no effect on the type of this expression

Viewed 64313

I searched about this but I didn't find anything specific for what I need. If there is one, please, share here.

I'm trying to create a generic service to be called in various components. Since it's a function that requests data from an external source, I need to treat it as an asynchronous function. Problem is, the editor returns the message "'await' has no effect on the type of this expression". And the app indeed crashes since there is no data yet.

People.js calls the service requests.js

import React, { useEffect, useState } from "react";
import requests from "../services/requests";

export default () => {

   // State
   const [ people, setPeople ] = useState({ count: null, next: null, previous: null, results: [] });

   // Tarefas iniciais
   useEffect(() => {
       carregarpeople(1);
   }, []);

   // Carregando os dados da API
   const carregarpeople = async (pageIndex) => {
       const peopleResponse = await requests("people", pageIndex);

       // This line below needs to be executed but it crashes the app since I need to populate it with the data from the function requests
       // setPeople(peopleResponse);
   }


   return (
       <div>
       {
           people.results.length > 0 ? (
               <ul>
                   {
                       people.results.map(person => <li key = { person.name }>{ person.name }</li>)
                   }
               </ul>    
           ) : <div>Loading...</div>
       }
       </div>
   )
  }

And this is requests.js, where it returns the json from API

export default (type, id) => {
console.table([ type, id ]);

fetch(`https://swapi.co/api/${type}/?page=${id}`)

.then(response => response.json())
.then(json => {
    console.log(json);
    return json;
})}

enter image description here

5 Answers

I was getting this error just because my JSDoc comment was incorrect.

For example I had an async function that had @returns {string}:

  /**
   * Fetch from the swapi API
   *
   * @param {string} type
   * @param {string} id
   * @returns {string} JSON
   */
  export default async (type, id) => {
    console.table([ type, id ]);
    const response = await fetch(`https://swapi.co/api/${type}/?page=${id}`);
    const json = await response.json();
    console.log(json);
    return json;
  }

I was getting the "'await' has no effect on the type of this expression" warning - but the function looked correct.

However once I changed the JSDoc to @returns {Promise<string>} then the error disappeared:

  /**
   * Fetch from the swapi API
   *
   * @param {string} type
   * @param {string} id
   * @returns {Promise<string>} JSON
   */

You can also use the @async hint as the JSDoc documentation suggests:

/**
 * Download data from the specified URL.
 *
 * @async
 * @function downloadData
 * @param {string} url - The URL to download from.
 * @return {Promise<string>} The data from the URL.
 */

await is only useful if you use it with a promise, but requests does not return a promise. It doesn't have a return statement at all, so it's implicitly returning undefined.

Looks like you meant for it to return a promise, so here's your code with the return added in:

export default (type, id) => {
  console.table([ type, id ]);
  return fetch(`https://swapi.co/api/${type}/?page=${id}`)
    .then(response => response.json())
    .then(json => {
      console.log(json);
      return json;
    })
}

p.s, if you prefer to do this using async/await, it would look like:

export default async (type, id) => {
  console.table([ type, id ]);
  const response = await fetch(`https://swapi.co/api/${type}/?page=${id}`);
  const json = await response.json();
  console.log(json);
  return json;
}

if you are getting this with typescript, maybe it's because you're not returning a Promise

for example:
❌incorrect:

async delPerson (id: string): Partial<Person> {
    return await this.personModel.findByIdAndRemove(id);
}
deletedPerson = await this.personService.delPerson(body._id);
// in above line typescript thinks that he is awaiting for something which is not a promise

✅correct:

async delPerson (id: string): Promise<Partial<Person>> {
    return await this.personModel.findByIdAndRemove(id);
}
deletedPerson = await this.personService.delPerson(body._id);

in my case the issue was purely associated with the js-doc of the method.

My method already had the async modifier.

original:

/**
 * bla bla
 * @return {String} bla bla bla
 */

fixed:

/**
 * bla bla
 * @return {Promise<String>} bla bla bla
 */

I found the solution. This suggestion pops up because you have put a wrong object after await. You can completely get rid of this by putting a promise (without brackets) or a function that returns a promise after the await keyword.

Related