Angular JS Reacts to Modifications from Javascript

I'm a beginner with AngularJS and I am facing an issue where my elements are not updating when specific values change via JavaScript. The changes only reflect when the values are manually entered or blurred in the input box.

You can find my simple example, derived from the Angular Dev Guide, here: http://jsfiddle.net/3R5wn/

<!-- Angular HTML -->
<div ng-app="">
<div ng-controller="InvoiceCntl">
  <b>Invoice:</b>
  <br>
  <br>
  <table>
   <tr><td>Quantity</td><td>Cost</td></tr>
   <tr>
   <td><input type="integer" min="0" ng-model="qty" required id="myqty"></td>
   <td><input type="number" ng-model="cost" required ></td>
   </tr>
  </table>
  <hr>
  <b>Total:</b> {{qty * cost | currency}}
</div>
</div>
<button onclick="document.getElementById('myqty').value=document.getElementById('myqty').value*1+1;">Increment Qty</button>

In the Angular Controller JS:

//Angular Controller JS
function InvoiceCntl($scope) {
   $scope.qty = 1;
   $scope.cost = 19.95;
}

The total updates when the user manually changes the values in the quantity/cost boxes, but it doesn't update when the "Increment" button is clicked. Can anyone provide a solution for this scenario without resorting to hacky methods?

Some additional notes:

  • In my actual project, I plan to use a jQuery spinner widget for incrementing
  • I will be using a custom function for calculations instead of a simple expression
  • I believe that solving the issue in the provided example will apply to my use case with the spinner/custom function

BIG EDIT

This is the actual code I am working with:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html ng-app="">
  <head>
    <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/excite-bike/jquery-ui.css" type="text/css" rel="stylesheet" />

    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js" type="text/javascript"></script>
    <script src="script.js" type="text/javascript"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js" type="text/javascript"></script>
    <script>
    //inline JS here
    $(function() {
        var spinner = $( "#qtySpinner" ).spinner({
            spin: function( event, ui ) {
                qty++;
            }
        });
    });
    </script>
    <title>Angular Testing</title>
  </head>
  <body>
    <div ng-controller="InvoiceCntl">
      <b>Invoice:</b><br>
      <br>
      <table>
        <tr>
          <td>
            Quantity
          </td>
          <td>
            Cost
          </td>
        </tr>
        <tr>
          <td>
            <input id="qtySpinner" type="integer" min="0" ng-model="qty" required="" ng-change="calculate(qty,cost);">
          </td>
          <td>
            <input type="number" ng-model="cost" required="">
          </td>
        </tr>
      </table>
      <hr>
      <b>Total:</b> {{calculate(qty,cost)}}
    </div>
    <br>
    <b>Dummy Experimental Buttons</b>
    <br>
    <button onclick="alert($('#qtySpinner').val());$('#qtySpinner').val(10);">Set 10</button>
    <button ng-click="qty++">Inc</button>
  </body>
</html>

Javscript function:

function InvoiceCntl($scope) {
   $scope.qty = 1;
   $scope.cost = 19.95;
   $scope.calculate = function calculate(xval, yval) {
                        return xval * yval;
                    };
}

Answer №1

Angular is designed in a way that allows you to avoid direct DOM manipulation. Instead, you can simply include the calculation - which can be basic JavaScript - within an ng-click attribute:

<button ng-click="qty++">Increment Qty</button>

Another approach is to create a method on your $scope, and then call this method using ng-click:

function InvoiceCntl($scope) {
   $scope.qty = 1;
   $scope.cost = 19.95;
   $scope.increment = function () {
      $scope.qty++;
   };
}

Subsequently, you can invoke this function in your view:

<button ng-click="increment()">Increment Qty</button>

Update: If you need to update the scope from outside of the angular digest cycle, you must first obtain a reference to the scope, make the necessary changes, and then manually trigger $digest to ensure the view reflects these updates:

var scope = angular.element('#qtySpinner').scope();
scope.qty++;
scope.$digest();

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

The function FormatCurrency is non-existent

I need assistance with converting a textbox value into a currency using the jquery.formatCurrency-1.4.0.js plugin. My JavaScript function is set up like this: $(document).ready(function() { $('.currency').blur(function() { $(&apo ...

Create a custom hook that encapsulates the useQuery function from tRPC and provides accurate TypeScript typings

I have integrated tRPC into a project that already has API calls, and I am looking to create a separate wrapper for the useQuery function. However, I am facing challenges in getting the TypeScript types right for this customization. My Objective This is w ...

Error: Jest encountered a TypeError stating that the require(...) function is not valid

Using React with ES6 in the application involves using ES6, where import and export statements are utilized. The problem arises when Jest is configured to work seamlessly with ES6, but compiled dependencies in the node_modules directory result in the follo ...

What is the best way to connect the user-input data with text in a span element?

Recently, I've started learning Vue.js and I'm facing an issue with binding data from an input field to a span element. Instead of appending the data, it's showing me undefined Here is the code snippet: new Vue({ el: "#app", data: { ...

angular ui-router child state resolve being overridden by parent's definition

I find myself in a perplexing situation where I have two distinct states within my code. var books = { name: "books", url: "/books", component: "booksComponent", } var specificBook = { name: "books.specific", url: "/{Id}", compo ...

What potential drawbacks could arise from frequent utilization of setImmediate?

One thing I'm curious about is whether the heavy use of setImmediate can have a negative impact on performance. To illustrate this, I've put together a simple example algorithm. Similar code to this would run every time an HTTP request is made. c ...

Error message: The Vue component is unable to assign a value to the 'render' property of an undefined object

The console is displaying an error message that reads: Uncaught TypeError: Cannot set property 'render' of undefined at normalizeComponent (componentNormalizer.js?2877:24)... This error is preventing my view from rendering and seems to be t ...

initiating various nodemon instances using a bash script

We have transitioned to a microservices architecture and I am looking to implement a bash script that can easily switch between different locales of our service. As someone new to bash scripting, this is my initial attempt at creating such a script. #!/bi ...

Utilizing JavaScript and node.js to access the MNIST dataset for reading

I'm currently working on decoding a dataset that I sourced from this link: At the bottom of the page, there is a description of the "very simple" IDX file type, but I am having difficulty understanding it. My goal is to achieve something similar to ...

Setting up TailwindCSS in Nuxt3: A step-by-step guide

Looking to customize the default font Proxima Nova from TailwindCSS in my Nuxt3 project but navigating the file structure is a bit tricky for me. I've gone ahead and installed the tailwindcss module: npm i -D @nuxtjs/tailwindcss and added the module ...

What is the best way to send a JavaScript array to a Perl script using AJAX?

Is it possible to convert a JavaScript array passed via AJAX into a Perl array? Accessing in Perl: @searchType = $cgi->param('searchType'); print @searchType[0]; Result: employee,admin,users,accounts It appears that the first value in the ...

Utilizing AJAX within an Ember.RSVP.Promise

I'm curious about the necessity of using the "return" keyword in the common code snippet below when invoking AJAX requests. Specifically, is it necessary for the $.ajax function (considering that $.ajax already returns a promise), or does it serve ano ...

Steps to emphasize HTML content and store it in the database for later use

I am currently working on a project that involves highlighting selected text within an HTML page that is loaded using PHP + XSL transformation. While I have come across solutions for highlighting the current selected text, I require the functionality to sa ...

sound not functioning on iPad

<audio id="example" controls="controls"> <source src="1.mp3" type="audio/mpeg" /> <source src="1.ogg" type="audio/ogg" /> </audio> JavaScript code to automatically play video when the page loads document.getElementById(&ap ...

The medium-zoom feature is currently experiencing issues with functionality within Angular version 13

I've been attempting to incorporate medium-zoom functionality into my project using https://www.npmjs.com/package/medium-zoom Here are the steps I took: ng new medium_zoom_test (Angular 13) with routing & css npm install medium-zoom The image is ...

Error: Discord bot encountered a TypeError while attempting to access the property 'id' of an undefined value

After revisiting a previous Discord bot package designed to track website updates, I encountered an issue. The code was originally scraped and last edited about 8 months ago with success. However, upon running node index.js, the following error occurred. ...

Leveraging AngularJs with MongoDB and Mongoose

I am working on connecting AngularJS with MongoDB using Mongoose. My goal is to pass the Models to controllers so that I can utilize $scope to access the data. I am unsure about setting up an Angular Service for this purpose, and would appreciate any guida ...

Encountering an issue with Server Side Rendering in React Router Dom where an error message pops up saying: "Warning: React.createElement: type is

Specific Error: A warning has occurred: React.createElement: the type provided is invalid -- it was expecting a string (for built-in components) or a class/function (for composite components), but instead received an object. in Posts in Connect(Po ...

Generating a component and rendering it according to the dynamic route parameters using mapStateToProps and reselect techniques

I have set up a global app container to store data for different rooms, with a sub-container called roomDetails that utilizes a reselect selector to pick a room from the global state based on ownProps.params.slug. This process is accomplished through mapSt ...

AJAX has caused the webpage to freeze, prompting a warning about potentially slowing down the browser

My website features an AJAX call to the Alpha Vantage API, which retrieves JSON data on stock symbols and tickers as users type in the search box. function handleKeyPress() { var keywords = document.getElementById("TextBox89 ...