AngularJS $scope.$watch doesn't detect changes when the input box is cleared

Recently, I delved into AngularJS and encountered a challenge while attempting to share data between two ng-controllers within the same ng-app module using a factory. Surprisingly, the data (HTML input field) from controller1 mostly gets shared with controller2. However, a peculiar issue arises when I delete all contents of the input field, as the $watch functionality fails to work as expected. Describing this quirk in words is proving to be challenging, so I have included screenshots below for clarity.

Below is the snippet of my code:

<!DOCTYPE html>
<html>
  <head>
    <% include ../partials/head %>
  </head>

  <body class="container" ng-app='myApp'>

    <div ng-controller="ctrl1">
        <input type="text" ng-model="firstName">
        <br>
        Input is : <strong>{{firstName}}</strong>
    </div>

    <div ng-controller="ctrl2">
        Input should also be here: {{firstName}}
    </div>


    <script>

        var myApp = angular.module('myApp', []);

        myApp.factory('Data', function () {
            var data = {
              FirstName: ''
            }

            return {
              getFirstName: function () {
                  return data.FirstName;
              },
              setFirstName: function (x) {
                  data.FirstName = x;
              }
            }
        });

        myApp.controller('ctrl1', function ($scope, Data) {
            $scope.firstName = ''

            $scope.$watch('firstName', function(newVal){
              if(newVal){Data.setFirstName(newVal);}
            });
        });

        myApp.controller('ctrl2', function ($scope, Data) {
            $scope.$watch(function(){return Data.getFirstName();}, function(newVal){
              if(newVal){$scope.firstName = newVal;}
            });
        });
    </script>

  </body>

  <footer>
        <% include ../partials/footer %>
  </footer>
</html>

For those interested, I have also shared a relevant jsfiddle link: http://jsfiddle.net/5LL3U/2/

Your assistance on this matter would be greatly appreciated. Thank you!

Answer №1

Ensure to compare both the newValue and the oldValue in your code. When the newValue is empty, the factory method will not be called and the variable value will not be set.

var myApp = angular.module('myApp', []);


myApp.factory('Data', function(){
    var data =
        {
            FirstName: ''
        };

    return {
        getFirstName: function () {
            return data.FirstName;
        },
        setFirstName: function (firstName) {
            data.FirstName = firstName;
        }
    };
});

myApp.controller('FirstCtrl', function( $scope, Data ) {

    $scope.firstName = '';

    $scope.$watch('firstName', function (newValue,oldValue) {
        console.log(oldValue+"   "+newValue);
        if (newValue!=oldValue) Data.setFirstName(newValue);
    });
});

myApp.controller('SecondCtrl', function( $scope, Data ){

    $scope.$watch(function () { return Data.getFirstName(); }, function (newValue,oldValue) {
        if (newValue!=oldValue) $scope.firstName = newValue;
    });
});

Fiddle:-http://jsfiddle.net/1d1vL1hd/

Answer №2

Your statement is inaccurate. If the newValue is empty, it evaluates to falsy and the firstName variable remains unchanged.

function updateFirstName(newValue) {
    if (newValue) {
        Data.setFirstName(newValue);
    }
}

Therefore, you should consider modifying or removing your conditional check.

Answer №3

When using $scope.$watch for 'object', it's important to include the true parameter for object equality. This ensures that the watch is triggered every time the value changes.

Remember, when sharing data between controllers, it's better to use a service instead of a factory.

Answer №4

Here's a suggestion: try simply eliminating the if (newValue) check from your code.

Check out the demo 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

After loading the ajax content, remember to include the JavaScript files

Here's the situation: I am importing some php files, one of which includes a slider that requires .js files. However, when I make an ajax call, the file is imported but the js files are not. Is this normal behavior? I attempted the following: var s ...

Easily targeting elements and their descendants in jquery: What you need to know!

Within a div, there are nested divs that contain tables and other divs. How can I use jquery to select both the parent div and its children? The parent div has the class "AccordionTitle AccordionTitle-selected". I have attempted the following: var klo=$( ...

`Technical challenges with input parameters and validation of forms`

I have a form that contains multiple input fields. To streamline the process, I came up with the idea of creating a directive to group and manage commonly used fields. Here is an example of how my form looks: <form name="aForm"> <input type= ...

Refusing to include two values due to the presence of a comma in JavaScript

I'm trying to add two values with commas and .00 (Example: 1,200.23 + 2,500.44) but it's not working because the textbox includes commas as required by my system. The result shows NaN because the comma is considered a special character. It was w ...

Is there a way for me to implement this code to achieve the functionality shown in the demo link

$('select').change(function() { var sum = 0; var sum = parseInt($('select[name="bathrooms"]').val() * 25) + parseInt($('select[name="bedrooms"]').val() * 8); $("#sum").html(sum); }); <script src="https://ajax.googleap ...

Checking for null values using the "and/or" syntax

While reading an article on special events in jQuery, I came across a syntax that was unfamiliar to me: var threshold = data && data.threshold || 1 I have previously encountered the following: var threshold = data.threshold || 1 As far as I kno ...

Ways to update the content of a NodeList

When I execute this code in the console: document.querySelectorAll("a.pointer[title='Average']") It fetches a collection of Averages, each with displayed text on the page: <a class="pointer" title="Average" onclick="showScoretab(this)"> ...

Using AJAX to set a session variable in PHP

Upon clicking a div, this JavaScript function is executed: $('.test').click(function(e) { e.preventDefault(); $.ajax({ url: 'ajax.php', type: 'POST', data: {"id": "<? ...

What is the procedure for eliminating an event listener that does not directly invoke a function?

I have implemented an event listener in my JS file following a successful AJAX request: var pageButtonsParentElement = document.getElementById("page-buttons"); pageButtonsParentElement.addEventListener('click', event => { ...

An issue occurred with the DOMException while trying to execute the 'setAttribute' function on the 'Element': '{{' is an invalid attribute identifier

Currently, the code is under development and some methods are still empty while the *ngIf directives may not be correct in terms of logic. However, even with these issues, I encountered the same error without bothering to remove them at this stage. While ...

Obtain base64 representation of a file using plupload file uploader

I am currently utilizing the Plupload Uploader. My objective is to convert the uploaded file to base64 and transmit it within a SOAP envelope. I have successfully created the envelope and utilized my web-service. However, I am wondering how I can retrieve ...

Using PHP Escape Functions in JavaScript

Can anyone help me with displaying item descriptions retrieved from a database query? Here is the code snippet that should display the description along with other details... <?php $type = "item"; $limit = 16; $preparedStatement = $SQL->prepare(& ...

Disabling $routeprovider while implementing bootstrap

I am encountering an issue with my normal routeprovider code. In a specific section of my HTML, I have some Twitter Bootstrap expand/collapse sections which inadvertently trigger the routeprovider when clicked. Is there a way to prevent this from happening ...

The JavaScript confirm function will provide a false return value

Is it necessary to display a confirmation message asking "Are you sure ..."? I have implemented the message, but the function return false; is not working when the user clicks NO. <script> function confirmDelete(){ var answer = confirm("Are you su ...

Adding the same block of code to an event in Node.js: Best practices

My preferred tech stack for real-time user synchronization includes Node.Js with Express and Express HBS (Handlebars), as well as Socket.IO. For example, when creating a web chat application, I emit an event from the client to the server each time a user ...

What is the best way to invoke JavaScript from C# code in Ext.NET?

Within my project, I encountered a situation where the displayed time in Chrome is incorrect while it appears correctly in Explorer. To address this issue, I wrote a JavaScript code, but unfortunately, it did not resolve the problem. Below is the JavaScrip ...

Using JavaScript to invoke Applescript commands

Is it feasible to execute Applescript from JavaScript? I would be grateful if someone could offer a sample code or useful reference link. ...

Next.js is like Gatsby but with the power of GraphQL

I'm curious if it's possible to set up GraphQL in Next.js similar to how it's done in Gatsby, allowing me to query pages and retrieve data from them. Are there any plugins available for Next.js that work like Gatsby-file-source and gatsby-ma ...

Determining the total number of documents through aggregation while implementing skip and limit functionality

Is there a way to retrieve the total count of documents when implementing aggregation along with limit and skip in a query similar to the one below? db.Vote.aggregate({ $match: { tid: "e6d38e1ecd", "comment.top ...

Add HTML syntax highlighting to a text area for coding purposes

I am facing a seemingly straightforward issue, but I worry that it may be too complex for me to handle on my own. My goal is to incorporate a textarea into a webpage where users can input HTML code, click a button, and have the interpreted HTML displayed i ...