When Controller Scope Goes Missing in ng-repeat

Upon glancing at my code, it should be evident that I am a newcomer to the world of Angular.

I am currently developing an application that enables users to search for text, queries a database whenever the value in the text input changes, and displays a list of matches. The backend is straightforward and operational. On the frontend, I have implemented the search field and the results container:

<div id="search" ng-controller="FormController">
    <input type="text" class="form-control input-lg" placeholder="Start typing . . ." ng-keypress="search()" ng-model="searchField" id="search-field">

    <div id="results" class="alert alert-success">
        <a href="#" ng-href="#" ng-repeat="item in items" ng-click="add(item)">
            <p class="lead text-left">
                <span>{{item.DisplayName}} -</span>
                <span> {{item.Description}} -</span>
                <span> {{item.Count}} ct. -</span>
                <span> ${{item.Price}}</span>
                <span class="glyphicon glyphicon-check pull-right"></span>
            </p>
        </a>
        <h4>{{noResults}}</h4>
    </div>
</div>

Two methods are called within my controller:

$scope.search = function()
{
    $scope.$watch('searchField', function (newValue)
    {
        if (newValue)
        {
            $http.post('/search', 
            {
                val: newValue
            })
            .success(function (response)
            {
                if (response.length > 0)
                {
                    $scope.items = response;
                    $scope.noResults = '';

                }
                else 
                {
                    $scope.noResults = 'No Matches Found';
                    $scope.items = '';
                }
            })
            .error(function (response)
            {
                console.log('Oooops, error: ' + response);
            });
        }
    });
};

$scope.add = function(item)
{
    console.log('added');
};

$scope.search() is functional but add() method does not trigger on click. It seems like I may not be within the scope of the controller at that point. Despite extensive research, I am stuck and seeking assistance. I have reached the frustrating "banging-your-head-against-the-keyboard-and-hopint-for-it-to-magically-work" phase.

Could this possibly be related to an inheritance issue?

** Update ** Here is the complete controller (with the $watch removed as suggested in the comments):

var app = angular.module('AppModule', ['toastr']);

app.controller('FormController', ['$scope', '$http', 'toastr', function($scope, $http, toastr)
{

    $scope.search = function()
    {
        var searchText = $scope.searchField;

        $http.post('/search', 
        {
            val: $scope.searchField
        })
        .success(function (response)
        {
            if (response.length > 0)
            {
                $scope.items = response;
                $scope.noResults = '';

            }
            else 
            {
                $scope.noResults = 'No Matches Found';
                $scope.items = '';
            }
        })
        .error(function (response)
        {
            console.log('Oooops, error: ' + response);
        });
    };

    $scope.add = function(item)
    {
        console.log('added');
    };

}]);  

Update 2

Here is a plunker demonstrating that everything works up until the add() method (which may have been renamed). Instead of my $http post, I have hardcoded a simulated response from the server.

Answer №1

Dealing with a CSS problem? Try commenting out line 8382 in your stylesheet (specifically the code that sets #results to display as none). Once you do this, the issue should be resolved. However, how you choose to address this in your CSS moving forward is another matter.

Answer №2

After reviewing your plunker, it appears that the issue I found was quite trivial.

Initially, I tried removing the class has-value from resultsContainer using a timeout, which resolved the issue with addItem.

  setTimeout(function() {
      resultsContainer.removeClass('has-value');
  }, 1000);

While this approach may work, I realized that utilizing setTimeout is not ideal.

Upon further exploration, I discovered that the problem stemmed from using display:none for #results. I decided to remove the display CSS property and utilize opacity instead.

    #results {
      position: absolute;
      /*display: none; */
       opacity : 0; 
      top: 100%;
      left: 0;
      width: 100%;
    }
    #results.has-value {
      display: block;
       opacity : 1;
    }

This adjustment resolved the issue without the need for a timeout. **I have encountered similar issues in the past where using display:none caused functionality problems. It's important to either adjust your CSS or use a timeout as an alternative solution.**

Additionally, I recommend considering moving that code into a directive for better organization.

You can view the updated plunker here

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

Unlocking the potential of Vue within shadow dom environments

I am facing an issue with a shadow DOM that includes the root element and a Vue component. <template> <div class="container"> <div id="app"></div> </div> <script src="http://my-site.com/app/js/vue-compo ...

Guidelines for attaching a div to the bottom of a page?

I have a navigation menu inside div.wrapper, and I am trying to make the div.wrapper stick to the footer. <div class="wrapper"> <div id="menu"> <ul> <li>1.</li> <li>2.</li> ...

What is the best way to eliminate the alert message "autoprefixer: Greetings, time traveler. We are now in the era of CSS without prefixes" in Angular 11?

I am currently working with Angular version 11 and I have encountered a warning message that states: Module Warning (from ./node_modules/postcss-loader/dist/cjs.js): Warning "autoprefixer: Greetings, time traveler. We are now in the era of prefix-le ...

What is the best way to determine the value of margin-left in inline CSS using jQuery?

Here is the code snippet I am working with: <div class="ongoing" style="width: +728px; margin-left: +12480px"> I need to extract the value of the margin-left property for scrolling purposes. The technique I used to retrieve the width value does no ...

Using Fabric.js to manage image controls situated beneath another overlay image

I'm currently working on a canvas user interface using jquery and the fabric.js library. I managed to add an overlay png image with transparency by implementing the code below: var bgImgSrc = bgImg.attr('src'); canvas.setOverlayImage(bgImgS ...

Using jQuery UI to create sortable lists that are connected and have hidden overflow features

How can I hide overflow from two fixed-height divs containing sortable lists connected to each other without affecting their connection? For example, if overflow is set to hidden, the list item doesn't display when dragged outside of the div. I' ...

Only one ID is recognized by jQuery

I have a group of three checkboxes set up like this: <input id="image_tagging" class="1" type="checkbox" value="1" checked="checked" name="data[image_tagging]"> Now, I've created an AJAX function (which is functioning correctly), but it seems ...

Comparing XDomainRequest and XMLHTTPRequest - which one to choose

Our team is currently developing an application utilizing PixiJS that integrates a dynamic json loader. The .json files are loaded using the following logic: if(window.XDomainRequest) { this.ajaxRequest = new window.XDomainRequest(); } else if (windo ...

Iterate through the list retrieved from the backend

I have a list coming from the backend that I need to iterate through and hide a button if any element in the list does not have a status of 6. feedback The response returned can vary in length, not always just one item like this example with 7 elements. ...

What could be the reason why the Google Maps API fails to load on Firefox?

I am currently utilizing the v3 version of Google Maps API. While my map functions perfectly in Safari and Chrome, I encountered an issue in Firefox where I received the error message "google.maps.Map is not a constructor." When inspecting 'google.ma ...

I'm having trouble understanding how to utilize startAt and endAt in Firebase version 9

Trying to implement geo querying in my firestore db with the new version of firebase has been challenging. The code examples provided in the documentation reference an older version, making it difficult for me to understand how to use ".startAt" and ".endA ...

Error: Import statement is not allowed outside of module scope

I've been through multiple documentations and sources, but I'm still struggling to fix this error. I recently started learning JavaScript and decided to experiment with fetch() commands, however, I keep encountering an issue (the title). Below i ...

Having trouble accessing req.user on my Node.js server using Auth0 and Angular

Currently, I am utilizing auth0 for my admin panel's login system and it is functioning smoothly. However, I have encountered an issue in node where 'req.user' is returning as undefined for some unknown reason. This setup is fairly basic; I ...

JavaScript Regular Expression for separating a collection of email addresses into individual parts

I am very close to getting this to work, but not quite there yet. In my JavaScript code, I have a string with a list of email addresses, each formatted differently: var emailList = '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data- ...

Issue with datetime picker in JavaScript/jQuery: Input fields added dynamically are not showing the datetime picker

I am currently investigating why the datetime picker does not work on a dynamically added input block within a table cell. A code snippet below serves as a proof of concept for this issue. In its present state, the default input tag (id: dti1) functions co ...

The angular.json file contains a script and a styles property

After encountering issues with adding styles and scripts to my angular.json file, I discovered that neither Bootstrap nor other scripts were taking effect. It turns out there are two places where you can define scripts and styles in the angular.json file a ...

how to use jQuery to locate the immediately preceding node that meets specific criteria

How can I locate the nearest parent node above $(this) node that has a specific property such as class="field", without considering parent/child relationships? ...

Sending an array of objects in JavaScript to a controller

I have a dynamic form that I'm trying to submit to my Controller. Instead of sending just a string or an array with data, I need to pass an array of objects using ajax request after building the Javascript Array. The challenge is that when I send only ...

Ways to modify the attribute of an element in an ImmutableList({}) nested within Immutable.Map({})

Is there a way to modify the property of an item within an ImmutableList({}) that is nested inside an Immutable.Map({})? This is my current setup: const initialState = Immutable.Map({ width: window.board.width, height: window.board.height, li ...

How can I ensure that my rendering only occurs after a full input has been entered? Implementing a delayed render() in ReactJS

Im working on a form that includes Controlled Component text inputs: <input type="text" onChange={(e) => this.props.changeBusiness(e)}/> I'm thinking of rendering the above text input in a separate component. It would be great if I could re ...