Asyncronous calls in Angular involve executing tasks without

The issue seems to be related to the timing of updates for the controlSelected and isAssessmentDataLoading variables. The updateQuestions() method is invoked within the ngOnInit() method, which is triggered when the component is initialized.

However, the assessmentData.securityControl variable is not populated until the setAssessmentData() method finishes, which occurs asynchronously.

Consequently, the updateQuestions() method is invoked before the assessmentData.securityControl variable is updated, leading to the controlSelected variable remaining true even when a valid security control is present. How can this be resolved?

I intend to modify updateQuestions() so that it is triggered upon successful retrieval of the assessment.

ngOnInit() {
  this.setAssessmentData(this.navigationService.getSavedID());

  this.isControlSecurityComplete = this.navigationService.getControlSecurityComplete();

  if (this.isControlSecurityComplete) {
    this.dataService.selectedSecurity$.subscribe((value) => {
      this.selectedSecurity = value;
    });
    this.questions.forEach(question => {
      question.selectedOption = null;
    });
  }
}

setAssessmentData(assessmentID: string) {
  this.assessmentService.getAssessmentById(assessmentID).subscribe(
    (assessment) => {
      this.assessmentData.nomeAssessment = assessment['nomeAssessment'];
      this.assessmentData.dataAssessment = assessment['dataAssessment'];
      this.assessmentData.nomeStruttura = assessment['nomeStruttura'];
      this.assessmentData.nomeCittaOSito = assessment['nomeCittaOSito'];
      this.assessmentData.statoProvinciaRegione = assessment['statoProvinciaRegione'];
      this.assessmentData.contatti.nome = assessment['contatti'] ? .nome;
      this.assessmentData.contatti.ruolo = assessment['contatti'] ? .ruolo;
      this.assessmentData.contatti.email = assessment['contatti'] ? .email;
      this.assessmentData.selectedCategory = assessment['selectedCategory'];
      this.assessmentData.securityLevel = assessment['securityLevel'];
      this.assessmentData.securityControl = assessment['securityControl'];
      this.assessmentData.domande = assessment['domande'];
      this.assessmentData.rispostaChatGPT = assessment['rispostaChatGPT'];

      if (this.assessmentData.securityControl == '') {
        this.controlSelected = true;
      } else {
        this.updateQuestions(this.assessmentData.securityControl);
        this.controlSelected = false;
      }
    },
    (error) => {
      this.isAssessmentDataLoading = false;
      console.error('Error retrieving assessment', error);
    }
  );
}

updateQuestions(controlName: string) {
  this.dataService.getJsonDataNew(controlName).subscribe((data) => {
    if (data && data.fileDocument && Array.isArray(data.fileDocument.fileData)) {
      this.questions = data.fileDocument.fileData.filter((item: any) => item.Security <= this.selectedSecurity);
    } else {
      this.questions = [];
    }
  });
}

Answer №1

Primarily, avoid getting caught up in nested subscribe() calls as it's considered an anti-pattern. This approach makes it challenging to control the emission of values and may lead to unresolved values.

When subscribing to getAssessmentById and adding a subscribe() for dataService.getJsonDataNew(), you unintentionally step into anti-pattern territory. This could be the underlying cause of the issues you are encountering in managing subscriptions.

A more effective strategy would involve refactoring your code and utilizing RxJS operators. SwitchMap can help in organizing your subscriptions more efficiently.

The updated code snippet is as follows:

setAssessmentData(assessmentID: string) {
    this.assessmentService.getAssessmentById(assessmentID).pipe(
      filter(Boolean), // to avoid null values
      switchMap((assessment) => { 
        this.mapAssessmentData(assessment);
  
        if (this.assessmentData.securityControl) {
          this.controlSelected = false;
          return this.dataService.getJsonDateNew(this.assessmentData.securityControl);
        } else {
          this.controlSelected = true;
          return of(false);
        }
      })
    ).subscribe(
      (val) => {
        if (val) {
          if (val.fileDocument && Array.isArray(val.fileDocument.fileData)) {
            this.questions = val.fileDocument.fileData.filter((item: any) => item.Security <= this.selectedSecurity);
          } else {
            this.questions = [];
          }
        }
      },
      (err) => this.handleError(err) // Handle errors in a separate function
    );
  }
  
  handleError(error: any) {
    console.error('Error:', error);
  }

function mapAssessmentData(assessment: any) {
    // Mapping data from assessment object
}

For dependencies with other subscriptions, consider using combineLatest or other merging operators based on your requirements.

Hope this explanation aids you in resolving the issues. Happy coding!🙂

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

Express server unable to process Fetch POST request body

I'm currently developing a React app and I've configured a basic Express API to store user details in the database app.post("/register", jsonParser, (req, res) => { console.log("body is ", req.body); let { usern ...

Creating a Tailored Validation Function in Angular 6

Looking to develop a custom generic validator that accepts the regular expression pattern and the property name (from a formgroup) as parameters? Take a look at this code snippet: UserName: new FormControl('', [ Validators.require ...

Implementing React and Material UI: Maximizing Vertical Space Usage for a Box Component

Currently, I am working on a web application using React combined with Material UI. Within my code snippet below, you will see three Box components in play. Box 1 and Box 3 have specific heights set, but I am looking for a way to make Box 2 occupy the re ...

Guide on how to conditionally render Container Classes

Initially, the designer provided me with this: Essentially, a category is passed from the previous screen. Through some UI interactions, I have to render this screen repeatedly. The flow goes like this: you choose a category, if it has subCategories, allo ...

Tips for attaching an event listener to activate a server-side email feature?

I have a setup with an express application that serves up a static index.html page. Additionally, there is a function in my app.js file that sends an email whenever the server starts running. My goal is to modify this so that the email is only sent when a ...

What is the best way to assign JSON values to my class property?

I've been working on a weather application that showcases the current weather of 5 different cities. By clicking on each city, users can access a detailed view displaying the 5-day forecast for that particular location. Currently, I have defined a we ...

Having trouble extracting information from JSON object array following an AJAX post?

My website transfers data through JSON objects using Angular's $http post. If you'd like to see the console logs and responses, visit my website: Initially, I used x-form-urlencoded encoding successfully and decided to switch to application/jso ...

JQuery/JS function not functioning as expected

Creating HTML with jQuery to retrieve data from a web API. At the start of my script, I defined a function that checks the selected value of a dropdown and assigns it to a global variable. var $seldom; $(document).ready(function () { function chkdom() ...

Having issues with closing a div tag using $.after() function

This issue can be better understood with an example: http://jsbin.com/lavonexuse The challenge here is to insert a full-width row after a specific column (identified by the class .insertion-point) when "Insert Row" is clicked. The problem I'm facing ...

ng-if directive does not show data in AngularJS

I have a dynamic collection of images and videos that I want to display one at a time. Specifically, when I click on an image ID, I want it to show the corresponding image, and when I click on a video ID, I want it to show the relevant video. Below is the ...

"Trouble in Transmitting: Node.js Fails to

As a beginner in programming, I am currently following a tutorial to enhance my skills. I've encountered a roadblock and I can't seem to successfully post new entries using the code. I'm struggling to identify what I might be missing here. ...

What steps should be taken to guarantee that the view is created only after receiving values from the route params subscription?

How can I ensure that the View is only rendered after the subscription has received values? When clicking on the Edit button in MyComponent_1, Angular navigates to MyComponent_2. In MyComponent_2, the view contains a form whose values are dependent on rout ...

Is it possible to pass an Array into a callback function in element-ui's el-autocomplete component?

I attempted to utilize the el-autocomplete tag in its simplest form: using an Array returned by a callback function (JSFiddle version). Vue.component('button-counter', { data: function() { return { selectdusers: [], user: &ap ...

Do discrepancies exist between ' and " symbols?

Similar Question: When to Use Double or Single Quotes in JavaScript Difference between single quotes and double quotes in Javascript I scoured this site and did some internet sleuthing (in that order...) trying to find the answer to this burning q ...

tips for passing value to the date field using proctractor

This is the HTML code I am working with: <input id="filter-datepicker" type="daterange" ranges="ranges" class="form-control date-picker" placeholder="Select Date Range" name="sensorDetails.date" ng-model="myDateRange" ranges="ranges" requi ...

Utilizing AngularJS to display a table with Rowspan functionality and the ability to filter elements

I am trying to develop an HTML table that utilizes rowspan with ng-repeat to group data effectively. The overall layout is functioning as expected, but I encountered a problem when attempting to apply filters to the table. Specifically, when I filter the ...

Automatically update local library dependencies with npm

Utilizing the local package dependency functionality of npm, I have implemented it in the following manner: npm install --save "file:/path/to/module" After updating my library module by running npm run build to generate dist files, I then execut ...

Shifting the placement of a component in Vue JS when hovering the mouse

I am facing an issue regarding the positioning of components. I have four images, and when you hover over them, a specific component is displayed as shown below: https://i.sstatic.net/gybcy.png For example, hovering over a yellow image will display a dif ...

Issue with Angular FormControl Pattern Validator failing to validate against regex pattern

My goal is to restrict a text input field to specific characters only. I am looking to allow: alphanumeric characters (a-z A-Z 0-9) 3 special characters (comma, dash, single quotation mark) : , - ' A few accented characters: à â ç è é ê î ô ...

Identifying the moment when the hide() function in jQuery is triggered for an element

Is there a way to detect when the .hide() method in jQuery is triggered on an element? I attempted to attach an event listener to the hide event of that particular element: $('div').bind('hide', function(){ alert("Hidden&q ...