Base solution for your next web application
Open Closed

delay in angular loop including call to API #7738


User avatar
0
BobIngham created

Hi guys, banging my head against a wall here so I thought I would reach out. I have a piece of server code which reads a default Word document store in blob storage. It then carries out a merge with these documents using entity data and then saved back to a different folder in the same container with a similar folder structure but under a unique folder created for the relevant entity. All relevant uri's are persisted in SQL Server for each document review. The cost of this when processing all documents in one go is considerable:

I have changed my server code to deal with individual requests and a delay between each. But I can't put a delay on the angular code so I can debug:

    checkedIds.forEach((id) => {
      let input = new LoadDefaultDocumentInput();
      input.ncEntityId = this.ncEntity.id;
      input.ncDocumentTemplateId = id;

      //setTimeout(function () {
        this._ncDocumentService.createDefaultDocument(input)
          .pipe(delay(10000))
          .subscribe((response) => {
            this.newDocumentLoaded.emit(response);
            if (id === _.last(checkedIds)) {
              this.allDocumentsLoaded.emit(true);
              setTimeout(function () {
                this.showModalForDocumentsLoading.emit(false);
              }, 5000);
            }
          });
      //}, 10000);

    });

Can anyone tell me why this .pipe(delay(10000)) command is not working? I have the requisite import from rxjs:

import { of } from 'rxjs/internal/observable/of';
import { delay, concatMap } from 'rxjs/operators';

Any ideas anyone?


5 Answer(s)
  • User Avatar
    0
    musa.demir created
        this._ncDocumentService.createDefaultDocument(input)
              .pipe(delay(10000))
              .subscribe((response) => {
               //your logic
              });
    

    This usage should work. Are you sure your logic in the subscriber method works correctly? Can you please check it?


    You may also try that way.

     timer(10000).pipe(switchMap(() => this._ncDocumentService.createDefaultDocument(input)))
                .subscribe(x => {
                    //your logic
                });
    

    By the way using internal imports may increse your bundle size. You can import 'of' like:

    import { of } from 'rxjs';
    
  • User Avatar
    0
    musa.demir created

    If you want to delay between each request you can call second request in first request's subscriber. Thus, all requests run sequentially and with a delay of 10sec between them.

  • User Avatar
    0
    BobIngham created

    @demirmusa -

    If you want to delay between each request you can call second request in first request's subscriber. Thus, all requests run sequentially and with a delay of 10sec between them.

    How would that work?

  • User Avatar
    0
    musa.demir created
     this._ncDocumentService.createDefaultDocument(input)
              .pipe(delay(10000))
              .subscribe((response) => {
              //your logic
               this.craeteNextDocument();
              });
    

    It will wait 10sec and send request. Then when request is done, it will call second one.

  • User Avatar
    0
    BobIngham created

    Hi @demirmusa, the problem was one of closure within javascript, as explained in the first answer here: setTimeout not working inside forEach. My refactored code is as below (note the use of the index parameter when setting the timeout at the end.

        selectedDocumentTemplates.forEach((item, index) => {
    
          setTimeout(function () {
            item = item.replace('dt_', '');
            input.ncDocumentTemplateId = item;
            console.log(input.ncDocumentTemplateId);
    
            self._ncDocumentService.createDefaultDocument(input)
              .subscribe((documentDto) => {
                self.newDocumentLoaded.emit(documentDto);
                if (index === selectedDocumentTemplates.length - 1) {
                  self.allDocumentsLoaded.emit(true);
                  setTimeout(function () {
                    self.showModalForDocumentsLoading.emit(undefined);
                  }, 5000);
                }
              });
          }, 5000 * (index + 1));
        });
    

    Thanks for your help.