Using *ngIf can lead to a never-ending cycle that never gets resolved

I am currently working on a project using Angular and I need to conditionally display a form based on certain values. I have successfully tested the backend route using Postman and everything is functioning correctly. Here is a snippet of my code:

Blockquote Angular Component HTML

<div *ngIf="canEdit()">
    ...
</div>

The above code snippet is where the function is being called

Blockquote Angular TS File

  canEdit() {
let username = this.currentUser.user.username;
let values = {
  "_id": this.org._id,
  "user": username
}
return this.http.post<any>('http://localhost:3001/users/compareUser', values, { withCredentials: true }).subscribe(
    result => {
      if (result.message == "All good!") {
        console.log(result);
        return true;
      } else {
        return false;
      }
    }
  )

Currently, when I run the code, it seems to be stuck in an infinite loop displaying {result: "All Good!"}. Interestingly, if I modify the canEdit() function to just return true and add a console log statement to track its execution count, it only runs once. However, with the existing code (TS), it does not seem to recognize the 'return true' statement that follows the console log.

Express route

    router.post("/compareUser", function(req, res, next) {
  let token = req.cookies.token;
  let id = req.body._id;
  let user = req.body.user;
  if (token) {
    Org.findById(id, (err, result) => {
      if (err) {
        console.log(err);
        return res.status(401).json({
          message: "Could not find Organization"
        });
      } else {
        User.findOne({ username: user }).then(user => {
          if (!user) {
            return res.status(401).json({
              message: "Are you sure you exist?"
            });
          } else {
            if (user.username == result.username) {
              return res.status(200).json({
                message: "All good!"
              });
            }
          }
        });
      }
    });
  } else {
    return res.status(404).json({
      message: "You must be logged in"
    });
  }
});

Answer №1

The canEdit() method is currently returning a Subscription instead of a boolean, which can be fixed by introducing a variable in the component class and using it instead of the method itself:

isValid = false;

ngOnInit() {
 this.checkIfUserCanEdit();
}

checkIfUserCanEdit() {
let username = this.currentUser.user.username;
let values = {
  "_id": this.org._id,
  "user": username
}
this.http.post<any>('http://localhost:3001/users/compareUser', values, { withCredentials: true }).subscribe(
    result => {
      if (result.message == "All good!") {
        console.log(result);
        this.isValid = true;
      } else {
        this.isValid = false;
      }
    }
  )
}

Update your template accordingly:

<div *ngIf="isValid"></div>

Answer №2

Another method is to simply return the observable itself and utilize the | async pipe.

canEdit() {
   let username = this.currentUser.user.username;
   let values = {
      "_id": this.org._id,
      "user": username
   }
    //Ensure that an observable is returned
    return this.http.post<any>('http://localhost:3001/users/compareUser', values, { withCredentials: true })
    //Use map to convert the response into a true or false value
    .pipe(map(result=>{
        return result.message=="All good!"?true:false
    })
}

Additionally,

<div *ngIf="canEdit()|async">
    ...
</div>

(*)In addition to Leo's answer

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

Adding onBlur validation for radio buttons and checkboxes in Angular Material UI

Currently, I am working on implementing checkboxes and radio buttons using Angular Material UI. My main issue lies in achieving the desired red outline effect when a required field is left unselected by the user. Even after applying the necessary 'req ...

Tips for eliminating the trailing slash from the end of a website article's URL

I've recently delved into learning Gatsby, and I've encountered an issue with the Open Graph tag in my project. The og:image is displaying a different image than the intended thumbnail for the article. Here's an example article - . When try ...

Discover local points of interest with the Google Places API integration on your WordPress site through PHP programming

$(document).ready(function() { var image_src = "images/"; var map; var infowindow; var bounds = new google.maps.LatLngBounds(); var PlaceArray = ["restaurant", "cafe", "bar", "grocery_or_supermarket", "parks", "school", "shopping_mall", "movie_t ...

Merging two arrays by their corresponding IDs and indexes

Within my current project, I am working with two arrays. The first array, arr1, contains a questionID property that I need to use to combine it with arr2 based on the condition where arr1 questionID equals arr2 index. For example, if arr1 questionID is 1, ...

Utilize the "Required" directive within a nested property

If I have a TypeScript type defined as follows: type State = { one?: string; two?: { three?: { four?: string; five?: string; six: number }, seven: string } } Is there a way to create a new type based on State where only ...

What is the best way to generate a new DIV every time a button is clicked?

I am attempting to make a square DIV that is red and measures 100x100 pixels. Each time a button is clicked, I want the square to be created. However, the code I have written is not functioning properly: <html> <title> Create New Div ...

Tips for preventing countdown from resetting when you refresh the page

I'm currently using a countdown feature on my Shopify website that is functioning well, except for one issue - whenever the page is refreshed, the countdown resets itself. Can anyone provide guidance on how to solve this problem? Thank you in advance! ...

Error encountered: popper.js throwing an unexpected token export SyntaxError

Error in Angular: When using popper.js with bootstrap 4, I'm encountering a SyntaxError with Unexpected token export. The error is showing up in the browser console. I tried changing the reference location for popper.min.js but it didn't work. ...

The function does not throw a compiler error when a parameter is missing

Currently utilizing TSC Version 2.4.2 Please take note of the following interface: interface CallbackWithNameParameter { cb: (name: string) => void } This code snippet: const aCallback: CallbackWithNameParameter = { cb: () => {} }; Manages t ...

The div inside an iframe is not displaying the desired background color as intended from the parent page

The code snippet below is included in the <head> section of the main page: <script type="text/javascript"> $(document).ready(function () { $('#innerframe').load(function () { $(this).contents().find($(".TitleB ...

React Material-UI TextField with Throttling

After exploring React Material UI, I am interested in implementing a TextField component that offers both debouncing and controlled functionality. When we refer to "controlled," we mean that the value persistence is managed externally, with the component a ...

one-time occurrence of $mdToast injection within a parent class

Seeking advice on how to efficiently place a single instance of $mdToast (from Angular Material) into a base class (Typescript). In my UI, I have five tabs with separate controller instances and it seemed logical to centralize the $mdToast declaration in a ...

Are fp-ts and Jest the perfect pairing for testing Option and Either types with ease?

When working with fp-ts, and conducting unit tests using Jest, I often come across scenarios where I need to test nullable results, typically represented by Option or Either (usually in array find operations). What is the most efficient way to ensure that ...

Exploring the capabilities of a Vue.js component

I am currently facing some challenges while trying to test a Vue.js component. My main issue lies in setting a property for the component and verifying that it has been set correctly. For context, the module has been loaded with exports and the JavaScrip ...

Steps to transfer data from a form input to a separate component using a service in Angular

In my setup, I am working with two components and hoping to gather input from one form and transmit this data to the other component. The first component looks like this: this.dal = this.form_search.get('dal').value; this.service.sendDataToSeco ...

Sending Text Input Data from Angular Form to a Restful API

I'm currently working on a project where I need to send data from a reactive form to a REST API running on my local express.js server. The form consists of basic text input fields like name, surname, and email. When the form data is submitted, it is ...

Integrating Highcharts Annotations with a donut chart

I'm struggling to find a way to position annotations for a donut chart outside of the donut itself. I've experimented with the distance, x, and y properties, but none have given me the desired outcome. Is there a method to properly position the a ...

Looping through an array and adding its elements to a dictionary using JavaScript

I am struggling to figure out how to iterate over a dictionary with values in the form of arrays and then organize those values into a new dictionary. I am unsure of the steps needed to achieve this. Below is the data I need to iterate through: { t: [&quo ...

Trouble with implementing Ajax in Express and jquery

My app has a browse page where users can add items as owned or wanted. Currently, when adding an item it redirects back to the general /browse page. However, I want the page to not refresh at all. I'm attempting to achieve this with ajax, but as a beg ...

XMLHttp request experiencing mixed content issues

Struggling with obtaining OAuth Tokens from a POST request through the Bungie API using javascript and XMLHttpRequest. Despite both my website and the API endpoint being secure (https), every post request I send returns a Mixed Content page error. I'v ...