Updating ngModel using the value retrieved from a service call

After experiencing dissatisfaction with Angular's form validation, I decided to develop my own solution. However, I have encountered a perplexing issue that has me at a loss.

Here is how my setup looks:

  1. I employ a directive to create a new form.
  2. The controller accesses the relevant form schema, which is utilized to generate fields in the view using ng-repeat.
  3. These input and textarea fields are then linked to the controller through ng-model.
  4. Upon field alteration or form submission, the controller forwards the form data to a validation service, which returns an error if needed, subsequently binding it to the DOM.

The challenge arises when attempting to implement a sanitation step before the validation process described in part 4. This step should update the controller data with the return value from a service method, refreshing the DOM binding and allowing the validation process to use the updated value. Despite updating the controller value itself, this change does not reflect in the DOM.

Below is snippet of the pertinent code:

View:

<div ng-repeat="(field, value) in form.schema">
  <!-- ... -->
  <textarea ng-model="form.data[field]" ng-model-options="{ updateOn: 'blur' }" ng-change="form.changed(field)"></textarea>
  <div class="message">{{ form.errors[field] }}</div>
</div>

Controller:

// Controller submit method
ctrl.submit = function () {

  var err;

  for (var field in ctrl.schema) {
    ctrl.data[field] = validationService.sanitizeField(ctrl.data[field], ctrl.schema[field]);
    ctrl.errors[field] = validationService.validateField(ctrl.data[field], ctrl.schema[field]);
    if (ctrl.errors[field] !== undefined) {
      err = true;
    }
  }

  if (err) {
    return;
  }

  // Proceed ...

Service:

// Public field sanitation method
var sanitizeField = function (value, schema) {
  try {
    // Try sanitation
  }
  catch (e) {
    // Error
  }
  return value;
}

While logging the new value of ctrl.data[field] in the controller post-sanitation yields the correct output, this result is correctly passed to the subsequent validateField method. Nonetheless, the altered data value fails to update in the DOM.

Initially, I suspected issues pertaining to scope application or promises. However, modifying the service and controller accordingly did not resolve the problem. Furthermore, wrapping the return value of sanitation in an object proved ineffective.

Interestingly, changing the return value in the service from the value variable to a primitive value like 'test', prompts an update in the DOM upon return.

Similarly, errors returned from the service validation method (also strings rather than variables) are displayed appropriately in the DOM.

Despite conducting extensive research on the topic, I have been unable to find solid answers. Any insights would be greatly appreciated!

Answer №1

Issue Resolved!

I recently discovered that Angular comes equipped with the ngTrim directive, which is automatically linked to input fields and is initially configured as true [Documentation].

This directive ensures that data is trimmed before being captured by the controller upon form submission - my sanitation service's trimming function was redundant as it didn't alter the data, leading to no changes being detected by Angular in the DOM.

To address this issue, simply set ng-trim="false" on pertinent fields within your view.

Answer №2

Here are some steps you can follow:


  for (var item in controller.schema) {
    controller.data[item] = angular.copy(validationService.sanitizeField(controller.data[item], controller.schema[item]));
    controller.errors[item] = angular.copy(validationService.validateField(controller.data[item], controller.schema[item]));
    if (controller.errors[item] !== undefined) {
      errorFlag = true;
    }
  }

Dealing with objects/arrays with nested properties in Angular can be challenging. To ensure that updates are reflected, consider using $scope.$watchCollection or angular.copy() to update the DOM.

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 Uib-Dropdown functionality is not functioning properly when placed within the body of an HTML view

After correctly installing the following dependencies: "ui-bootstrap": "0.12.2", "ngAnimate": "1.5.5", "AngularJs": "1.5.5 I encountered an issue with creating a dropdown menu in my HTML view. Despite no visible errors and successful implementati ...

Press the delete button located on the child component to trigger an action in the

I'm in the process of developing a simple to-do application from scratch in order to familiarize myself with ReactJS. One challenge I'm facing is implementing the delete functionality for todos, as I want to keep the button within the Todo compon ...

obtain the text content from HTML response in Node.js

In my current situation, I am facing a challenge in extracting the values from the given HTML text and storing them in separate variables. I have experimented with Cheerio library, but unfortunately, it did not yield the desired results. The provided HTML ...

Click to load additional data until the list has reached its full length

<ng-container *ngFor="let item of itemList | slice:0:3"> <mat-checkbox>{{item}}</mat-checkbox> </ng-container> <div> <button id="loadMore">Load More</button> </div> I wo ...

"Exploring the possibilities of Ajax in conjunction with Sol

I recently completed a tutorial on Ajax Solr and followed the instructions in step one. Below is the code I wrote: header.php: <script type="text/javascript" src="static/js/ajax-solr/core/Core.js"></script> <script type="text/javascript" s ...

Ways to bring in external javascript files in reactjs

I'm currently working on a form that requires the user to input their location. To achieve this, I have integrated the npm package react-geosuggest-plus. However, I want to avoid including <script src="https://maps.googleapis.com/maps/api/js?key=AI ...

Breaking apart a mesh using THREE.js

Can a single THREE.Mesh be divided into multiple meshes? For instance, can a mesh with 2,000,000 polygons be split into 2,000 meshes each with 1,000 polygons? Edit: Realistically, it may not be possible to retain the exact same number of polygons/vertice ...

When using Vue computed, an error is thrown stating "Issue in rendering: 'InternalError: too much recursion'" if the same key is referenced in computed

As a newcomer to Vue, I wanted to track how many times a function in the computed section gets called. To achieve this, I created the following component: const ComputedCounter = { name: "ComputedCounter", template: ` <span>{{ value } ...

Tips for interpreting JSON information and showcasing it with the assistance of Ajax in JQuery?

There's a request made to the system via AJAX that returns JSON as a response, which is then displayed in an HTML table. The HTML code for displaying the data looks like this: <table id="documentDisplay"> <thead> <tr ...

Discover the final index of an array with Angular's ng-repeat functionality

I'm currently working with an Object that contains array values which I am trying to iterate over. Here's a simplified example of what I have: $scope.messages = { "1": [ { "content": "Hello" }, { "content": "How are you" }, { "conte ...

Compilation failure due to Typescript initialization issue

Encountering a TypeScript error in my IntelliJ-Idea 2017.1.1 IDE I have enabled JavaScript, NodeJS, and TypeScript Compiler. I have exhausted all solutions but the issue persists, perhaps I am missing something. Error: Initialization error (typescript ...

Creating an HTML table using an array of objects

I'm currently working on creating a function that will generate an HTML table from an array of objects. The array provided below is what I need to convert into a table. let units = [ { 'code': 'COMP2110', &apos ...

Setting up a div as a canvas in Three.js: Step-by-step guide

Is there a way to adjust the JavaScript in this three.js canvas example so that the scene can be contained within a specific div element on a webpage? Here is the example: https://codepen.io/PedalsUp/pen/qBqvvzR I would like to use this as the background ...

"An issue with the colyseus server has been detected within the JavaScript code

I have written some code but it seems to be causing errors. const colyseus = require("colyseus"); const http = require("http"); const express = require("express"); const port = process.env.port || 3000; const app = express(); ...

Once the window width exceeds $(window).width(), the mouseenter function is triggered exponentially

My side menu smoothly folds to the right or left based on the size of the browser window. However, I noticed that upon first reload, the mouseenter and mouseleave events are triggered twice for each action. While this isn't a major issue, it becomes p ...

The getBBox() method of SVG:g is returning an incorrect width value

Hey there, I've been attempting to determine the width of a <g> element and it consistently returns 509.5 pixels regardless of what I do. Initially, I assumed this was the actual size and not scaled. However, upon opening the SVG in Illustrato ...

jquery ajax function that returns an object when successful

Below is a brief example of an AJAX call wrapped in a function. MyNS.GetStrings = function (successCallback, errorCallback) { var url = serverUrl + "/GetStrings"; $.ajax({ type: "GET", contentType: "application/json; charset=utf-8", dataType: ...

Tips on updating content at a specific time without the need to refresh the page

I'm working on a digital signage script that needs to be time scheduled. I was able to accomplish this using JavaScript and refreshing the page every 15 minutes. However, my question is, how can I track the time and update the content at specific hour ...

Customizing an array.map display in React Native

For my app, I am creating multiple drawers to showcase how it can be used. This is done by using the following code: Array(400).fill(info).map(info => {return <AlbumBox info = {info} />}) The information of an object is retrieved and passed into ...

Integrating XML API Requests Using HTML and JavaScript

When there is only one item in the XML document, I want to update my inner HTML with the result of an API call. I have managed to successfully make the API call work when there are multiple items in the XML document (thanks to W3). <!DOCTYPE html> ...