1

I am trying to make a modal in Angular 9 that returns a Promise as result. I don't know how to move the promise logic outside of the declaration.

<a class="button-primary" (click)="yes()">Yes</a>
<a class="button-default" (click)="no()">No</a>

This is the modal controller

import { Component, OnInit, HostBinding } from '@angular/core';

@Component({
  selector: 'change-username-modal',
  templateUrl: './change-username-modal.component.html',
  styleUrls: ['./change-username-modal.component.less']
})
export class ChangeUsernameModalComponent implements OnInit {

  @HostBinding('class.show')
  show: boolean = false;

  constructor() { }

  ngOnInit(): void {
    console.log('init');
  }

  public open(): Promise<boolean> {
    return new Promise(function(resolve, reject) {
      resolve(true);
    });
  }

  yes() {
    //this.myPromise.resolve(true);
    this.show = false;
  }

  no() {
    //this.myPromise.reject(false);
    this.show = false;
  }

}

I need to make the Promise resolve or reject when calling the yes() or no() functions. Thank you in advance!

Pacuraru Daniel
  • 1,207
  • 9
  • 30
  • 56
  • You could achieve this, very simple with observables, do you insist to have promise? – onik Jun 13 '20 at 16:22
  • i think a promise is more elegant since i only need a one-time answer from the modal – Pacuraru Daniel Jun 13 '20 at 17:31
  • Hmm, I dont think that observable is not elegant solution either. For exapmle you could chain your answer with switchmap pipe and send api request right away... just think about it as Angular httpclient even its only one time answer it is still returning observable – onik Jun 13 '20 at 17:38
  • But anyway, if you still need promise, you might look at this link https://stackoverflow.com/questions/26150232/resolve-javascript-promise-outside-function-scope – onik Jun 13 '20 at 17:42
  • is there an article where i can find the observable approach ? or maybe you can asnwer it so i can upvote and check it – Pacuraru Daniel Jun 13 '20 at 18:16
  • sure I'll rwrite it down – onik Jun 13 '20 at 18:17

1 Answers1

1

You could use Observable approach instead of promise. you need a simple subject which will emit and complete immediately (for avoiding memory leak). the code should look like this

export class Component{

  @HostBinding('class.show')
  show: boolean = false;

  private _emitter$ = new Subject<boolean>();

  constructor() { }

  ngOnInit(): void {
    console.log('init');
  }

  public open(): Observable<boolean> {
    return this._emitter.asObservable();
  }

  yes() {
    //this.myPromise.resolve(true);
    this.show = false;
    this.emitAndClose(true);
  }

  emitAndClose(answer:boolean){
     this._emitter.next(answer);
     this._emitter.complete();
  }

  no() {
    this.emitAndClose(false);
    this.show = false;

  }

}

now whenever answer is clicked, it will emit the value and complete the subject so you don't need unsubscribe outside

onik
  • 1,579
  • 1
  • 11
  • 19
  • i did pretty much the same before you answered but after opening it again, i would get 2 results so your .complete approach, now THAT is elegant. thank you very much! – Pacuraru Daniel Jun 13 '20 at 19:18