Issue with the code flow causing nested function calls to not work as expected

I'm experiencing an issue with my code:

The problem arises when param.qtamodificata is set to true, causing the code to return "undefined" due to asynchronous calls. However, everything works fine if params.qtamodificata is false.

I am seeking a solution to ensure the code flow remains synchronous, allowing the result to be returned only after the entire process has been completed.

Any suggestions on how to address this issue?

Thank you for your assistance

getOrderRow

public getOrderRow(params): Observable<any>
  {
    //OFFLINE SWITCH OK
    var res = { headers: [], data: [] }

    return Observable.fromPromise(this._WebDBService.sysConfigurazione.toArray().then(
      data => {

        var art = JSON.parse(data[0].ordinidatajson).filter(
          function(itm,index){
            return itm.codart.v === params.codart;
          }
        );

        res.headers = JSON.parse(data[0].ordiniheaderjson);

        if(params.qtamodificata == true)
        {
          this.getQuantities(art[0].codart.v,null,params.udmmodificata, params['qtaord'+ params.udmmodificata]).subscribe(
            qtys =>{
                  art[0].qtaord1.v = qtys.dqta1;
                  art[0].qtaord2.v = qtys.dqta2;
                  art[0].qtaord3.v = qtys.dqta3;

                  res.data = art[0];

                  return res;
                }
              );          
        }
        else
        {
          res.data = art[0];
          return res;
        }                         
      }
    ));
  }

getQuantities

public getQuantities(codart: string, codvar: string, idqta: number, qta: number): Observable<any>{

    return Observable.fromPromise(this._WebDBService.tbArticoli.where({codart: codart}).toArray().then(
      data => 
      {
        console.log('getQuantities');               

        var qtys = {
          dqta1: 0,
          dqta2: 0,
          dqta3: 0
        }

        var a = data[0];

        switch (idqta) {
          case 1:
            qtys.dqta1 = +qta;
            if (a.rapudm12 > 0 && a.codudm2)
              qtys.dqta2 = qta / a.rapudm12;
            if (a.rapudm23 > 0 && a.codudm3)
              qtys.dqta3 = qta / a.rapudm23;
            break;
          case 2:
            qtys.dqta2 = +qta;
            if (a.rapudm12 > 0 && a.codudm1)
              qtys.dqta1 = qta / a.rapudm12;
            if (a.rapudm23 > 0 && a.codudm3)
              qtys.dqta3 = qta / a.rapudm23;
            break;
          case 3:
            qtys.dqta3 = +qta;
            if (a.rapudm23 > 0 && a.codudm2)
              qtys.dqta3 = qta / a.rapudm23;
            if (a.rapudm12 > 0 && a.codudm1)
              qtys.dqta1 = qta / a.rapudm12;
            break;
        }
        return qtys;

      }));    
  }

Function Call

this.orderService.getOrderRow(params, 'test')
          .subscribe(list => {
            console.log('onlineorder3');
            console.log(list);
            console.log('onlineorder3');
}

Answer №1

It appears that you are changing Promises to Observables. In this scenario, utilizing Promises along with async/await can enhance the clarity and comprehension of your code. A revised version could look like this:

public async getOrderRow(params): Promise<any> {
    //OFFLINE SWITCH OK
    var res = { headers: [], data: [] }

    var data = await this._WebDBService.sysConfigurazione.toArray();
    var art = JSON.parse(data[0].ordinidatajson).filter(
        function (itm, index) {
            return itm.codart.v === params.codart;
        }
    );

    res.headers = JSON.parse(data[0].ordiniheaderjson);

    if (params.qtamodificata == true) {
        let qtys = await this.getQuantities(art[0].codart.v, null, params.udmmodificata, params['qtaord' + params.udmmodificata]);

        art[0].qtaord1.v = qtys.dqta1;
        art[0].qtaord2.v = qtys.dqta2;
        art[0].qtaord3.v = qtys.dqta3;

        res.data = art[0];

        return res;

    }
    else {
        res.data = art[0];
        return res;
    }
}

public async getQuantities(codart: string, codvar: string, idqta: number, qta: number): Promise<any> {

    let data = await this._WebDBService.tbArticoli.where({ codart: codart }).toArray();
    console.log('getQuantities');
    var qtys = {
        dqta1: 0,
        dqta2: 0,
        dqta3: 0
    }
    // ... Omitted for brevity
    return qtys;
}

Note: I have utilized Promise<any> in the return types, however, it is recommended to specify a type that accurately describes the result. For instance, for getQuantities, the return value should ideally be

Promise<{dqta1:number, dqta2:number, dqta3:number }>
.

Answer №2

The issue I was facing got resolved after implementing forkJoin and making changes to the getOrderRow method:

 public updateOrderRow(params): Observable<any>
  {
    //OFFLINE SWITCH OK
    var response = { headers: [], data: [] }

    return Observable.forkJoin(
      Observable.fromPromise(this._WebDBService.systemConfiguration.toArray()),
      this.fetchQuantities(params.code, null, params.modifiedUdm, params['orderedQty' + params.modifiedUdm])
    ).map((
      result: any[]) => {      

        var updatedData = {headers: [], data:[]}

        var article = JSON.parse(result[0][0].orderDataJson).filter(
          function (item, index) {
            return item.code === params.code;
          }
        );

        article[0].orderedQty1 = result[1].quantity1;
        article[0].orderedQty2 = result[1].quantity2;
        article[0].orderedQty3 = result[1].quantity3;

        updatedData.headers = JSON.parse(result[0][0].orderHeadersJson);
        updatedData.data = article[0];

        return updatedData;
      }
    );

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

Using Vue js and Typescript to automatically scroll to the bottom of a div whenever there are changes in

My goal is to automatically scroll to the bottom of a div whenever a new comment is added. Here's what I have been trying: gotoBottom() { let content = this.$refs.commentsWrapper; content.scrollTop = content.scrollHeight } The div containing ...

What will be the output of this typescript function?

Whenever I hover over the keyword 'function', this cryptic description pops up: "(local function)(this: any, next: (err?: mongoose.CallbackError | undefined) => void): Promise<void>" I'm confused about whether it return ...

Issues arise when attempting to enforce type-safety in TypeScript while using the JSON.parse

Is it possible that type-safety is compromised in TypeScript when dealing with JSON parsing? I should be triggering an error, but I'm not: interface Person { name: string } const person: Person = somePossibleFalsey ? JSON.parse(db.person) : undefi ...

What's the best way to display a component once a function has been executed?

My service controls the visibility of components using *ngIf! Currently, when I click a button, the service sets to true and the components appear instantly! I want the components to only show after a specific function has finished executing. This means I ...

What could be causing the 404 error when trying to make a get-request to fetch a list of all users?

Having trouble retrieving a list of users using my endpoint, as it keeps returning a 404 error. I have set up a model, controller, router, and index file for the user in my application. Below is the User.ts model: import { Schema } from 'mongoose&apo ...

Tips on informing the TS compiler that the value returned by a custom function is not null

There might be a way to make this code work in TypeScript, even though it's currently showing some errors regarding possible undefined values. Take a look at the code snippet: const someArray: foo[] | null | undefined = [...] // TS fail: someArray ...

How can I run a TypeScript function within a JavaScript file?

I am working with a typescript file named file1.ts export function Hello(str: string) { console.log(str); } In addition, I have another file called index.js { require('./some.js'); } Furthermore, there is a script defined in the pack ...

What seems to be the issue with the useState hook in my React application - is it not functioning as

Currently, I am engrossed in a project where I am crafting a Select component using a newfound design pattern. The execution looks flawless, but there seems to be an issue as the useState function doesn't seem to be functioning properly. As a newcomer ...

Sort by label using the pipe operator in RxJS with Angular

I have a situation where I am using an observable in my HTML code with the async pipe. I want to sort the observable by the 'label' property, but I'm not sure how to correctly implement this sorting logic within the pipe. The labels can be e ...

How to apply dynamic styling to a MatHeaderCell using NgStyle?

My goal is to dynamically style a MatHeaderCell instance using the following code: [ngStyle]="styleHeaderCell(c)" Check out my demo here. After examining, I noticed that: styleHeaderCell(c) It receives the column and returns an object, however ...

Result of Mongodb aggregation operation

I've created a Property controller : //Retrieve Properties By Type const getPropertiesByType = async (req: Request, res: Response) => { const { cities, type } = req.query; const citiesArr = typeof cities === 'string' ? cities.spli ...

Calling the `firstValueFrom()` method in RxJS will keep the observable alive and not

Hey there, I'm currently having issues with using firstValueFrom(), lastValueForm(), and Observable.pipe(take(1)) in my TypeScript code with Angular 14 and RxJs 7.8.0. I am working with a Firebase server that provides stored image URLs via an API wit ...

Component opens MatSnackBar in various styles

I've been seeking a method to achieve the following: incorporating a custom SnackBar for displaying notifications. After consulting the official documentation (here), I successfully created a basic Snackbar with customized settings. this.snackBar.ope ...

You were supposed to provide 2 arguments, but you only gave 1.ts(2554)

Hey everyone, I hope you're having a good morning. Apologies for the inconvenience, I've been practicing to improve my skills and encountered an issue while working on a login feature. I'm trying to connect it to an API but facing a strange ...

"Upon submitting a form in React JS, the components will automatically trigger a

Within my application, there is a Mobx storage in conjunction with a modal window component. The form within the modal window allows me to collect all the properties and push them into an array named 'cart' within the storage as an object. Take a ...

The field 'name' is not recognized on type 'never'

Currently immersing myself in Angular and experimenting with making an API call, but I'm encountering the following error: error TS2339: Property 'name' does not exist on type 'never'. import { Component, OnInit } from '@angu ...

Numerous sentries summoning an asynchronous function

In my scenario, I have two guards - Guard1 and Guard2. Guard1 is responsible for returning an Observable whereas Guard2 returns a Boolean value. For canActivate: [Guard1, Guard2] If Guard2 were to return false, would the request made by Guard1 be automat ...

Changing md-sidenav mode in Angular Material 2

Looking to modify the behavior of the md-sidenav in Angular Material 2, switching from side on desktops to over on mobile devices. Is there a method to achieve this programmatically? Appreciate any guidance! ...

Displaying an Array in HTML using Angular

Just starting out with Angular and experimenting with data display from an array. The data in the array is: [Me, Three, Four] I attempted to loop through it for printing but encountered issues. Here's a snippet of how I'm currently handling it: ...

Incorporate an external JS file (File A) that is dependent on another JS file (File B) into a TypeScript file within the context of Angular 4

Working on an Angular 4 project, I recently installed two external JS libraries using npm. They are now in the node_modules folder and usable in another TS file within my project. The issue arises because import B requires import A, preventing me from effe ...