The promise chain from the ngbModal.open function is being bypassed

I'm currently working on implementing data editing within a component. My task involves checking if any of the data fields have been altered, and if so, prompting a confirmation pop-up to appear. If the user confirms the change, the data will then be updated.

Within the updateData() method, I am invoking the isChangeConfirmed() function which triggers the pop-up and verifies if the Save button has been clicked. Upon confirmation, it should return true. However, instead of returning control to the updateData() method after this step, the data gets saved first before the pop-up window is displayed. What could be causing this unexpected behavior?

component.html

<button id="saveButton" type="button" (click)="updateData()" translate>BUTTON.SAVE</button>


<!-- POPUP -->

<ng-template #editModal let-modal>
  <button type="submit" id="modalConfirmButton" (click)="modal.close('save')" class="btn btn-primary" translate>BUTTON.CONFIRM</button>
  <button type="reset" id="modalCancelButton" (click)="modal.close('cancel')" class="btn btn-primary" translate>BUTTON.CANCEL</button>
</ng-template>

component.ts

updateData() {
  if (this.isChangeConfirmed()) {

    // Code for updating data goes here

  }
}

isChangeConfirmed(): boolean {
  if (this.oldValue != this.newValue) {
    this
      .ngbModal
      .open(this.editModal, { ariaLabelledBy: 'editModal' })
      .result
      .then((result) => {
        return result == "save";
      }, (reason) => {
        return false;
      });
  }
  return true;
}

Answer №1

Upon opening the modal, there arises a quandary with the sections enclosed within

(result) => { /*asynchronous part*/ }
and
(reason) => { /*asynchronous part*/ }
, as they execute asynchronously. The timing of these executions in relation to the external sections remains indeterminate. Placing your return false; statement within the asynchronous context while positioning the return true; statement outside of it results in uncertainty regarding the execution order. It appears that, in this scenario, return true; executes more expeditiously than return false;. However, the precise sequence of events cannot be predicted.

While the setup may seem acceptable, inserting return true; inside

(result) => {... return true;}
will likely prompt a complaint from the compiler about missing a return statement.

To resolve this issue, two solutions come to mind:

  • Combine all code into one function instead of using a separate function, and place // Some code which updates data inside
    (result) => {... /* Some code which updates data*/ }
  • If you prefer to keep a separate function, alter the return type from boolean to an Observable, then subscribe to that Observable within updateData(). Explore how to combine the responses of (result) and (reason) into a single Observable, create an Observable from this amalgamation, and return it.

If you opt for the second approach, I recommend delving into RxJS Operators (https://rxjs.dev/guide/operators). Additionally, familiarizing yourself with articles on reactive programming can prove beneficial.

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

Upgrade Challenge from Angular 7 to Angular 9

I am currently in the process of upgrading my application from version 7 to version 9. However, I have encountered an issue with the new IVY compiler in Angular 9 not being compatible with the library angular-webstorage-service, resulting in the following ...

Is it acceptable to have an empty dependency array in React.useEffect?

Within my child React component, I receive an itemList prop from the parent component. This prop is an array of objects that contain data fetched from an endpoint. My goal in the child component is to enhance each object in the itemList array by adding mo ...

Ways to change the Date format to something like [25 Jan 2024]

https://i.sstatic.net/BvSc8.png I am looking to convert the date format to appear as "25 Jan 2024" in my Angular application. Currently, the date is displayed as "25-01-2024" but I want it to be in the format "25 Jan 2024". Can anyone help me resolve this ...

Angular2 form builder generating dynamic forms based on results of asynchronous calls

When creating my form, I encountered a challenge with passing the results of an asynchronous call to the form builder. This is what I have attempted: export class PerformInspectionPage implements OnInit { checklists: any; inspectionform: FormGroup; n ...

What is the correct way to include a new property in the MUI Link component using TypeScript?

Currently, within my mui-theme.ts configuration file, I have the following setup: const theme = createTheme(globalTheme, { components: { MuiLink: { variants: [ { props: { hover: 'lightup' }, style: { ...

Assigning object properties from a request to every item in an observable array of objects using RxJS

Despite my efforts to search various resources like mergeMap and switchMap, I am unable to solve the problem I'm facing as I am still new to RxJs. While I would like to provide more details about my attempts in this post, I fear it may complicate my q ...

Switching class on a specific element in Angular 2

My element list appears like this: <ul *ngFor="let period of periodsDate"> <li [class.show]="isShown" (click)="toggleClass()"> <a>{{ period.id }} </a> </li> </ul> ...

Angular 2/4 throws an Error when a Promise is rejected

I implemented an asynchronous validator function as shown below. static shouldBeUnique(control: AbstractControl): Promise<ValidationErrors | null> { return new Promise((resolve, reject) => { setTimeout(() => { if (contr ...

What is the significance of the error message "Surprisingly in Angular Zone despite expectations"?

Ever since upgrading from Angular 2 RC4 to RC5, I've been encountering this error. Although it doesn't seem to impact the application's functionality, it keeps appearing in the console and may draw attention away from other errors. Does any ...

The Observable merge operation encountered an error: it cannot access the 'apply' property of an undefined value

I am currently working on setting up a sorted DataTable in an angular application, and while implementing it using this example, I encountered the following error: ERROR TypeError: Cannot read property 'apply' of undefined at TableDataSource ...

How can you navigate to a particular page within a Single Page Application using NodeNS?

My NodeJS server is hosting a single page application that was built using Angular5. In certain circumstances, I need to direct users to a specific page within the application. For instance, during a designated time period, I want users to be redirected t ...

The compilation process encountered an error: TypeError - Unable to access property 'exclude' as it is undefined (awesome-typescript-loader)

After successfully converting my existing Angular 2 project into Angular 4, I encountered the following error: Module build failed: TypeError: Cannot read property 'exclude' of undefined For more details, please refer to the attached image bel ...

The role of providers in Angular applications

After creating a component and service in my project, I followed the documentation's instruction to include the service in the providers metadata of the component for injection. However, I found that it still works fine even without mentioning it in t ...

Using Typescript to incorporate Next.js on Firebase Functions

I'm currently working on deploying a Next.js application to Firebase Functions. import next from 'next' import {https} from 'firebase-functions' const server = next({ dev: process.env.NODE_ENV !== 'production', conf: ...

What limitations prevent me from utilizing a switch statement to refine class types in Typescript?

Unique Playground Link with Comments This is a standard illustration of type narrowing through the use of interfaces. // Defining 2 types of entities enum EntityType { ANIMAL = 'ANIMAL', PLANT = 'PLANT', } // The interface for ani ...

Embedded Facebook SDK posts appearing only after performing a hard refresh

I tried to implement sharing facebook posts on my client's website following the instructions provided in the Facebook embedded post documentation. The website is built using the React NEXT.js framework. I added the SDK right after opening the body ...

Instructions on utilizing type interfaces for prop drilling in my React Typescript counter

I am currently developing a basic counter app to monitor my progress in a digital card game that I enjoy playing. While attempting to pass props from the parent component to the child component, I encountered an issue where the props were not being success ...

Difficulty encountered when attempting to create a lambda function in TypeScript

I'm having trouble understanding the following lambda function definition in TypeScript. It could be a beginner question. type P = { id: string } type F = <T>(x: T) => string const f: F = (x: P) => x.id f({ id: 'abc' } However, ...

"Connecting multiple URLs to the same router link: A step-by-step guide

I am currently working on a small test project in Angular and I aim to incorporate a side navigation using Angular router outlet. My goal is to have two links: <a class="nav-link text-white" [routerLink]='["/link/to/one"]' routerLinkActive="a ...

What are the various methods of specifying function types in TypeScript?

I've noticed that in Typescript you can easily declare a function type using the declare keyword. For example: declare function test1(name: string): true const t1 = test1('t') // true Alternatively, you can also use the arrow notation: c ...