Using ng-if outside of ng-repeat can cause issues with ng-repeat loops in AngularJS

AngularJS Version: 1.3.8

JSFiddle Link: http://jsfiddle.net/uYFE9/4/

I've been working on a small AngularJS project and encountered an issue. I have implemented an ng-repeat in a form that gets populated based on the selection from a dropdown menu linked to a model using ng-options. Here is a snippet of the code:

<select id="testAmount" ng-model="selectedItem" ng-options="item.name for item in items"></select>

<form role="form" name="testForm" ng-if="!complete">
    <div ng-repeat="i in getNumber(selectedItem.number) track by $index">
        {{$index}}
    </div>
</form>

Initially, the variable complete is set to false. Clicking a Next button will toggle the value of

complete</code, hiding the form and dropdown. Pressing the <code>Back
button will then revert the value of
complete</code back, displaying the form again.</p>

<p>The issue arises with the use of <code>ng-if
on the select element (and previously, when I had the form enclosed in a div with the same ng-if). The ng-repeat stops updating when the selection in the dropdown changes. However, removing the ng-if from the select restores the functionality of ng-repeat.

I am unsure if there is a problem with the nesting structure or if it is a bug within AngularJS itself. Feel free to test it out on the provided JSFiddle link. The $index should be printed as many times as the selected number in the dropdown, but it does not display correctly.

An interesting observation is that when I debugged this issue on my local setup, having FireBug open seemed to resolve the problem.

Answer №1

The reason behind this issue is related to the ng-if directive creating a separate child scope and how primitive prototypical inheritance interacts with it. Specifically, when you set the value of selectedItem through the <select> element, it is actually assigned to the child scope, which then conceals or overrides the parent scope's property.

It is advisable to always incorporate a dot (.) notation in your ng-models:

$scope.selection = {selectedItem: undefined};

And in your HTML template:

<div ng-if="!complete">
  <select ng-model="selection.selectedItem" 
          ng-options="item.name for item in items"></select>
</div>

Answer №2

ng-if is causing scoping complications that are interfering with the binding process.

For a workaround, you can refer to this updated jsfiddle example. In this solution, another div is wrapped around the elements that need to be hidden. Additionally, a next function is included to ensure that the scope remains consistent when the click event occurs and sets complete to true.

HTML:

<div ng-app="test">
    <div ng-controller="TestCtrl">
        <div ng-if="!complete">
            <div>
                <label for="testAmount">Amount:</label>
                <select id="testAmount" ng-model="selectedItem" ng-options="item.name for item in items"></select>
            </div>

            <form role="form" name="testForm">
                <div ng-repeat="i in getNumber(selectedItem.number) track by $index">
                    {{$index + 'hi'}}
                </div>
                <button class="btn btn-default" value="Next" title="Next" ng-click="next()">Next</button>
            </form>
        </div>

        <div ng-if="complete">

        </div>
    </div>
</div>

JS:

angular.module('test', [])
.controller('TestCtrl', function($scope) {
    $scope.complete = false;

    $scope.items = [
        { name: '2', number: 2 },
        { name: '3', number: 3 },
        { name: '4', number: 4 }
    ];

    $scope.selectedItem = $scope.items[0];

    $scope.getNumber = function (number) {
        return new Array(number);
    };

    $scope.next = function() {
      $scope.complete = true;  
    };
})

Answer №3

It seems like the issue lies in the select statement within an ng-if condition, where the selectedItem is not getting properly set. If you do not want to display the dropdown when !complete, consider using ng-show instead, which should resolve the issue.

    <div ng-show="!complete">

As for why the ng-model is not being bound within the ng-if, it's a bit unclear. It could be due to attempting a conditional bind, which may result in unexpected behavior.

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

Delay the loading of HTML elements to improve website performance

While working on my portfolio, I noticed that the page load time is quite long due to all the images needing to load before the page is fully loaded. I started thinking if there is a way to delay or prevent the loading of images and then have them load la ...

Utilizing the ng-controller directive multiple times on DOM elements within an Angular application

I am facing an issue where I need to use the same controller on two DOM elements. After some research, I found out that using ng-controller on two elements will create two separate instances of the controller. To address this, I decided to share a variable ...

RequireJS in use with .NET Angular

I set up a fresh ASP.NET Empty Web Application using Visual Studios 2013. Within this project, I have an angular application organized in the following directory structure: ├───TestProject │ ├───index.html │ ├───package.jso ...

Utilizing Bootstrap Modal to Upload an Image

I'm facing an issue with uploading an image using a Bootstrap modal. The problem I encounter is that even after selecting an image, I continue to receive the validation error message "Your upload form is empty". Below is the script for my form in the ...

Exploring the contents of a JSON object

Just getting started with jquery and I'm attempting to parse a JSON object. This is my Jquery ajax call $(document).ready(function () { var resource = "v1/projects"; var url = '@Url.Action("Proxy")?resource=' + resource; ...

Is there a way to collect data from two input fields within a radio button selection?

My form has a radio button that determines whether a file input field or a text input field is shown based on the user's selection. I am facing an issue with extracting data from the radio button when there are two additional input fields involved. & ...

How to assign key-value pairs to two arrays in JavaScript?

Looking to convert two arrays into an object in JavaScript let ar1 = ['jhon', 'doe', 'alex']; let ar2 = ['21', '22', '35']; The desired output should be: obj=[ {name:'jhon',age:'21 ...

Issue with Angular JS: ng-repeat not refreshing within ng-view

Whenever I make changes to the data stored in the variable $scope.userMovies, ng-repeat fails to update when it is inside an ng-view. Strangely enough, if it's placed outside of ng-view, everything updates as intended. What could be the reason behind ...

Managing multiple Firebase Projects in Backend JavaScript

As a developer with multiple apps across various projects, I needed a way to efficiently retrieve information about them for future updates. This led me to create an API using NodeJS, where I configured endpoints to fetch data from different projects. For ...

If the modal PopUp is closed without canceling row editing in a gridview inside it, the PopUp will not reopen

In my project, I have a gridview that allows in-place editing and is placed within a modal popup extender. While everything works smoothly, the issue arises when I try to edit a row and input data that doesn't meet the validation rules set by RegularE ...

Can you suggest a simple method for implementing the "componentDidUpdate()" lifecycle method using just JavaScript?

I've been curious about replicating the componentDidUpdate() lifecycle method in JavaScript on my own. It got me thinking, how did React and Vue.JS create their own lifecycle methods? I attempted to study the minified version of Vue.JS but found it qu ...

How can one identify a concealed glitch that exclusively occurs for a particular individual or hardware in a React environment?

Is it possible to identify a bug that occurs only with a particular individual or hardware in a React application? This bug is invisible and never appears during tests, but only manifests with a specific client within my company. Do you have any tips on h ...

Utilizing $(this) in Jquery alongside css class selectors

In my HTML code, I have implemented a functionality to display and download tracks. The requirement is to hide the Play button, Download button, and Share button when the user clicks on the Share button. Instead, after hiding the default buttons, social me ...

JSON object representing a nested class

I am facing an issue while attempting to create a JSON object using JavaScript/jQuery. Specifically, I am trying to get the JSON object for Class A and encountering problems with the value of b1 being undefined. Class A { string test1; B b1; } Class B { ...

jQuery, Oops! Something went wrong

I have some JavaScript code on my website that is dynamically loading div elements onto the page. I also want to include onmouseenter and onmouseleave event handlers for each div. I have attempted to use jQuery to implement these handlers, but I am encount ...

What is the quickest method to perform a comprehensive comparison of arrays and combine distinct objects?

I am currently working with NextJS and Zustand and I have a state in Zustand that consists of an array of objects: [{a:1, b:2}, {a:2, b:3}] Additionally, there is another incoming array of objects that contains some of the existing objects as well as new ...

Utilizing KnockoutJS to Apply CSS Binding Based on Dropdown Selection

Check out the live example here: http://jsfiddle.net/0gmbbv5w/ In my application, I have an object retrieved from the database that I bind to a <select> var NoticeType = function (noticeType) { this.NoticeTypeId = ko.observable(noticeType.Notic ...

Creating a paragraph from text inputs using React

I'm currently working on code that retrieves input from two textboxes - one for a string value and one for a number value. I want this data to be displayed in real-time within a paragraph without the need for a submit button. I've been struggling ...

Avoid tampering with forms in PHP, JavaScript, and JQuery to maintain security measures for PayPal transactions

Users have the option to purchase credits on my form using PayPal or bank transfer as payment methods. If a user chooses "PayPal," the form data will be sent to PayPal using JQuery/JS: $(':radio').change(function () { var $this = $(this).val(); ...

The dropdown in the UIB Typehead is not displaying

I am facing an issue with the UI-Bootstrap typeahead where the dropdown does not display when the data is received. $scope.obtainUsers = function (valor) { console.log(valor) $http({ method: "POST", url ...