Chart of commitments and potential outcomes

I am in the early stages of learning about promises and I am struggling to understand how to write code correctly. Here is an overview of what the program should do:

  • Retrieve a list of item types (obtained through a promise)
  • Loop through each item type to check if any item of that type matches a given ID (using another promise)
  • If a match is found, return the item type, otherwise do nothing.

Below is the code snippet:

  public getItemTypeFromItemId(itemId: string): Promise<ItemTypeName[]> {
    console.log("Searching for ID " + itemId + " in all item types");
    return this.getItemTypes().then(itemtypes => {
      console.log("Found " + itemtypes.length + " item types.")
      let itemtypenames: ItemTypeName[] = [];
      const calls = itemtypes.map(itemtype => {
        console.log("Looking in " + itemtype.name);
        return this.getItemById(itemtype.name, itemId).then(value => {
          if (value !== undefined) {
            console.log("FOUND " + itemId + " within " + itemtype.name);
            // There is an item of this type with this id
            itemtypenames.push(itemtype.name as ItemTypeName);
          }
        });
      });
      return Promise.all(calls).then(() => itemtypenames);
    });
  }

Below are automated tests outlining the expected outcomes:

  const PART_ID = "2A1499A5563349DAA1597EFB375FA8F2";
  const CAD_ID = "24FCC02F8BD048C5881E1C63DAFC88BB";

  describe('"getItemTypeFromItemId": get ItemType from item ID', async function () {
    it('Finds the correct item type when the ID is present', async function () {
      await itemTypeService.getItemTypeFromItemId(PART_ID).then(itemtypenames => expect(itemtypenames[0]).to.equal("Part"));
      await itemTypeService.getItemTypeFromItemId(CAD_ID).then(itemtypenames => expect(itemtypenames[0]).to.equal("CAD"));
    });

    it('Returns `undefined` if no item with this ID exists', async function () {
      await itemTypeService.getItemTypeFromItemId("").then(itemtypenames => expect(itemtypenames.length).to.equal(0));
    });
  });

Answer №1

Your current issue is stemming from TypeScript's inference of the return type when using Promise.all. TypeScript is interpreting the return type of your function as Promise<ItemTypeName | (ItemTypeName | undefined)[]>, which may not align with your intended outcome.

To address this and ensure the return type remains as Promise whilst handling scenarios where nothing is found, you can adopt a slightly modified approach:

public getItemByIdWithoutItemType(itemId: string): Promise<ItemTypeName | undefined> {
return this.getItemTypes().then(itemTypes => {
    const requests = itemTypes.map(itemType => {
        return this.getItemById(itemType.name, itemId).then(value => {
            if (value !== undefined) {
                return itemtype.name as ItemTypeName;
            } else {
                return undefined;
            }
        });
    });

    return Promise.all(requests).then(results => {
        const validResults = results.filter(result => result !== undefined) as ItemTypeName[];
    
        if (validResults.length > 0) {
            return validResults[0];
        } else {
            return undefined;
        }
    });
});

}

Answer №2

It seems there is some confusion regarding the purpose of the function as pointed out by other commenters. It might be more beneficial to rewrite it using async/await, which simplifies working with Promises.

UPDATE: After considering your feedback, here is a revised version that aligns more closely with your requirements:

public async fetchItemsByIdWithoutType(
  itemId: string,
): Promise<ItemType[]> {
  const itemTypes = await this.retrieveItemTypes();
  const matchedItems: ItemType[] = [];
  await Promise.all(
    itemTypes.map(async (itemType) => {
      const foundItem = await this.fetchItemById(itemtype.name, itemId);
      if (foundItem !== undefined) {
        matchedItems.push(itemType.name);
      }
    })
  );
  return matchedItems;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ensuring Proper Tabulator Width Adjustment Across All Browser Zoom Levels

<div id="wormGearTabulatorTable" style="max-height: 100%; max-width: 100%; position: relative;" class="tabulator" role="grid" tabulator-layout="fitDataTable"><div class="tabulator-header" role="rowgroup"><div class="tabulator-header-co ...

The TypeScript namespace does not exist or cannot be located

Currently, I am working on coding in TypeScript. The specific code pertains to an Angular 2 application, but the main focus of my inquiry lies within TypeScript itself. Within my project, there are certain files that contain various models, such as the exa ...

Conducting computations on a series of layered python dictionaries

Attempting to generate a dictionary comprehension by comparing two nested dictionaries that are of similar size and subtracting the final value from the smaller nested dictionary. Only values that are not equal to 0 will be included in the dictionary. d1 ...

Unable to declare a string enum in TypeScript because string is not compatible

enum Animal { animal1 = 'animal1', animal2 = 'animal2', animal3 = 'animal3', animal4 = 'animal4', animal5 = 'animal5' } const species: Animal = 'animal' + num Why does typescr ...

What is the proper way to send a list as a parameter in a restangular post request

Check out this code snippet I found: assignUserToProject(pid: number, selectedUsers: any, uid: number) { let instance = this; return instance.Restangular.all("configure/assign").one(pid.toString()).one(uid.toString()).post(selectedUsers); } ...

A guide on implementing getStaticProps using TypeScript in Next.js

Why am I consistently receiving undefined results when attempting to retrieve all posts from my backend? What could be causing this issue? import { AppContext } from '@/helpers/Helpers' import axios from 'axios' import { GetStaticProps} ...

How can I populate dropdown options from an API in a react JS project using typescript and react saga?

Check out my page, where I am trying to fetch brand options from an API. Below is the saga I have implemented: Action.tsx export const getBrandsForDropdown = (request: IPagination) => { return { type: actions, payload: request ...

Error message appears when using TypeScript with a React Material table showing a generic type error

I am currently attempting to implement react-material in a Typescript project. As a newcomer to Typescript, I am encountering some errors that I am unsure how to resolve. In this gist, I am trying to create a reusable React component (Please view the gis ...

The practice of following the UpperCamelCase convention post object transformation

I encountered a situation where I have an object that returned the result from an RxJs subscribe method: result: any { message: null role: Object success: true } To better manage this object in TypeScript, I decided to convert it to a type ca ...

What allows the execution of "T[keyof T] extends Function" in TypeScript specifically for Strings?

Lately, I've been experimenting with type changes and I find myself puzzled when encountering code like the following: type DeepReadonly<T> = { readonly [k in keyof T]: T[k] extends Function?T[k]:DeepReadonly<T[k]> } // Let's defin ...

Wrapper around union function in TypeScript with generics

I'm struggling to find a solution for typing a wrapper function. My goal is to enhance a form control's onChange callback by adding a console.log. Can someone please point out what I might be overlooking? interface TextInput { type: 'Tex ...

Obtain abbreviated names for the days of the week starting from Monday to Sunday using JavaScript

Is there a way to retrieve the abbreviated names of each day of the week in JavaScript, starting from Monday through Sunday? ...

What is the process for attaching a key signature onto a string in order for it to function as an index for an object?

How can I specify a signature in TypeScript to indicate that the current value might be used as an index for accessing a specific object? I am encountering the error: Element implicitly has an 'any' type because expression of type 'string&ap ...

Implementing advanced error handling using custom error messages with enums

I'm trying to use Zod to validate a gender field with z.nativeEnum(), but for some reason my custom error messages are not being applied: gender: z.nativeEnum(Gender, { invalid_type_error: 'Le sexe doit être homme ou femme.', ...

Data not being retrieved by HTTP GET request

I encountered an issue with my API where I made three Get requests using the same function but different URLs to differentiate between them. However, even though the provider returns the data in steps, the page response function does not receive it and sho ...

Error in TypeScript: Module 'stytch' and its corresponding type declarations could not be located. (Error code: ts(2307))

I'm currently developing a Next.js application and encountering an issue while attempting to import the 'stytch' module in TypeScript. The problem arises when TypeScript is unable to locate the module or its type declarations, resulting in t ...

Typescript extra property specifications

I need some assistance with creating a custom input field using typescript and Formik. Can someone please help me figure out how to include additional props like label & name in the code snippet below? I've been stuck on this for a while and I have a ...

Angular Form: displaying multiple hashtags within an input field

Utilizing Angular CLI and Angular Material, I have created a form to input new hashtags. I am facing difficulty in displaying previously added hashtags in the input field. Below is the code I have written: form.component.html <form [formGroup]="crea ...

jQuery when - anticipate the fulfillment of multiple success/done callbacks

When using $.when to determine when an array of ajax promises are finished, I have noticed that although the ajax calls themselves are completed when $.when fires, their callbacks and done functions are not. How can I make sure to wait for the callbacks to ...

Tips for differentiating between elements with identical values in an HTML datalist using Angular

My boss is insisting that I use a datalist in our website interface to select an employee, even though there's no way to determine if the user typed in the name or picked from the list. The challenge is that the list must only display full names, but ...