Search code examples
javascripttypescriptuikites6-promisegetuikit

UIkit.modal.alert then chaining many functions


I have a uikit alert, I want to click OK button in the alert then doing many chaining things following the order.

UIkit.modal.alert('test')
   .then(() => {
     // blah blah 1
      this.httpClient('url1').get().subscribe(data => {
      this.field1 = data;
       });
   })
   .then(() => {
     // blah blah 2
       this.updateUi(this.field1);
   })
  .then(() => {
     // blah blah 3
     this.httpClient('url3').post({body: this.detail}).subscribe(data => {
         console.log(data);
     });
   })
  .then(() => {
     // blah blah 4
     this.anotherField = 'newValue';
  });

However the chaining is not working well. It seems sometimes it run the blah blah 4 first then run blah blah 1 or other random orders.

I use uikit 3.03

Also I am okay with js alert rather than uikit alert by the way.

UPDATE:

Per comments, I create a demo at https://stackblitz.com/edit/call-http-request-in-angular-6-wc5ahn


Solution

  • So you're mixing promises with other types of asynchronous operations. You could just do all promises to easily chain all async operations.

    const get = url => new Promise((resolve) => {
        this.httpClient(url)
                .get()
                .subscribe(resolve);
    })
    const post = (url, body) => new Promise((resolve) => {
        this.httpClient(url)
                .post({ body })
                .subscribe(resolve);
    })
    
    UIkit.modal.alert("test")
        .then(() => get("url1"))
        .then(dataFromUrl1 => {
            this.field1 = dataFromUrl1;
            this.updateUi(this.field1);
        })
        .then(() => post("url3", { body: this.detail }))
        .then(() => {
            // blah blah 4
            this.anotherField = "newValue";
        });
    
    

    Example of working order of operation where UIkit.modal.alert() is returning a promise.

    const get = url => new Promise((resolve) => {
        console.log("GETTING");
        resolve();
    })
    const post = (url, body) => new Promise((resolve) => {
        console.log("POSTING");
        resolve();
    })
    
    console.log('opening modal');
    UIkit.modal.alert("test")
        .then(() => get("url1"))
        .then(dataFromUrl1 => {
            console.log("finished getting :)");
        })
        .then(() => post("url3", { body: this.detail }))
        .then(() => {
            console.log("finished posting");
        });
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/uikit-icons.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/uikit.min.css" rel="stylesheet"/>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/uikit.min.js"></script>

    UPDATE given stackblitz link..

    Your current implementation is:

    const t = UIkit.modal
          .alert("test")
          .then(() =>
            get("url1").then(() => {
              this.http.get<Kafein[]>(this.url).subscribe(data => {
                this.httpData = data;
                console.log(data[0]);
              });
            })
          )
          .then(() => post("url3", { body: "detail" }));
    

    The problem is subtle yet not all the uncommon.. You are nesting chains when you do not need to. You can just chain without the nesting as such:

    const t = UIkit.modal
          .alert("test")
          .then(() => get("url1"))
          .then(() => new Promise((resolve, reject) => {
            this.http.get<Kafein[]>(this.url).subscribe(data => {
                this.httpData = data;
                console.log(data[0]);
                resolve();
              });
          }))
          .then(() => post("url3", { body: "detail" }));