Open Closed

Concurrency conflict handling in angular UI #2565


User avatar
0
LW created
  • ABP Framework version: v5.1.0

  • UI type: Angular

  • DB provider: EF Core

  • Tiered (MVC) or Identity Server Separated (Angular): yes According to this advice https://support.abp.io/QA/Questions/2284/Concurrency-handling-clarification-question , we now implemented updating concurrency stamp in every update method. However, we now have a problem that the "conflict" return value is not handled correctly in our Angular app. Backend returns 409 as expected. We get an exception page instead of an error dialog telling the user about the error like it was shown in the linked answer. I assumed that of course there is a default handling for conflict type return code, but couldn't find it from the angular source code.

  • Steps to reproduce the issue:" Add concurrency stamp update to an entities update method in application service, then update the entity concurrently from Angular UI


2 Answer(s)
  • User Avatar
    0
    LW created

    Any ideas for this?

  • User Avatar
    0
    muhammedaltug created

    Hello,

    Sorry for the late response. I try the following steps to reproduce your error. But I can't reproduce your error. Please check the steps.

    By the way, I see the error is 0 Unknown Error. This means the HTTP status code is 0. Could it be related to something else?
    By default error modal displays after the HTTP 409 error. You can check this file

    1. I created a new app with the app pro template in the 5.1.3 version.

    2. Add a new entity in the suite which named Book with the suite.

    3. Implement IHasConcurrencyStamp interface to BookUpdateDto and BookDto

      // BookdDto
      using System;
      using Volo.Abp.Application.Dtos;
      using Volo.Abp.Domain.Entities;
      
      namespace pro513.Books
      {
          public class BookDto : FullAuditedEntityDto<Guid>, IHasConcurrencyStamp
          {
              public string name { get; set; }
      
              public string ConcurrencyStamp { get; set; }
          }
      }
      
      // BookUpdatedDto
      using System;
      using System.ComponentModel.DataAnnotations;
      using Volo.Abp.Domain.Entities;
      
      namespace pro513.Books
      {
          public class BookUpdateDto : IHasConcurrencyStamp
          {
              public string name { get; set; }
      
              public string ConcurrencyStamp { get; set; }
          }
      }
      
    4. Generate proxies with abp generate-proxy -t ng command.

    5. Update BookAppService's UpdateAsyncmethod with the following lines

      [Authorize(pro513Permissions.Books.Edit)]
      public virtual async Task<BookDto> UpdateAsync(Guid id, BookUpdateDto input)
      {
      
          var book = await _bookRepository.GetAsync(id);
          ObjectMapper.Map(input, book);
          // this line added
          book.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp);
      
          book = await _bookRepository.UpdateAsync(book, autoSave: true);
          return ObjectMapper.Map<Book, BookDto>(book);
      }
      
    6. Update BookComponent's submitForm method with the following lines

      submitForm() {
          if (this.form.invalid) return;
          // service.update method's second parameter replaced from this.form.value to  {...this.selected, ...this.form.value}
          const request = this.selected
            ? this.service.update(this.selected.id, {...this.selected, ...this.form.value})
            : this.service.create(this.form.value);
      
          this.isModalBusy = true;
      
          request
            .pipe(
              finalize(() => (this.isModalBusy = false)),
              tap(() => this.hideForm())
            )
            .subscribe(this.list.get);
        }
      

    Result

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11