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 animation-play-state is set to 'running', however, it refuses to start playing

I'm in the process of creating a landing page that includes CSS animations, such as fade-ins. Initially setting animation-play-state: "paused" in the CSS file, I later use jQuery to trigger the animation while scrolling through the page. While this s ...

Stop users from being able to copy text on their smartphones' internet browsers

I am currently working on creating a competitive typing speed challenge using JavaScript. Participants are required to type all the words they see from a div into a textarea. In order to prevent cheating, such as copying the words directly from the div, o ...

Monitoring multiple items in OPC UA with Node.js

Utilizing the node-opcua module, my goal is to efficiently monitor multiple opc ua nodes through subscriptions. The desired workflow involves a user selecting nodes in an HTML UI, clicking a Monitor button which then sends the corresponding nodeIds as para ...

The left-hand operator in Typescript is not valid

I am a beginner in typescript and I have been following a tutorial called Tour of Heroes on Angular's website. In the final chapter of the tutorial, when I tried to use HTTP with the provided code, everything seemed to run fine but I encountered an er ...

Which is better: using multiple makeStyles or just one in Material UI?

Uncertain about the best approach in this situation. Is it acceptable to generate styles using makeStyles for each component individually, or would it be better to create one in the base component and simply pass down class names? ...

What is the best way to include the toast component in my button?

I am brand new to working with Next.js and React. I have a button in my project that triggers an external JavaScript file (query.js). After the script finishes executing, I would like to display a toast notification indicating whether it was successful or ...

"Learn how to efficiently incorporate data into data-binding in VUE JS with just a

In my data binding, there is a string that reads as follows: bc-men,bc-men-fashion,bc-men-underwear I want to create an input field where I can enter "bc-some-category", click "Add", and have it appended to the end of the list with a comma in front. Her ...

Steps for converting an HTML form into a sophisticated JavaScript object

Is it possible to transform a form into a complex JavaScript object based on a structured form layout? I am not sure if there is a better way to accomplish this, but essentially what I am looking for is the following scenario: <form> <input n ...

Tips for Saving JSON Response from Fetch API into a JavaScript Object

I am facing an issue trying to store a Fetch API JSON as a JavaScript object in order to use it elsewhere. The console.log test is successful, however I am unable to access the data. The Following Works: It displays console entries with three to-do items: ...

Display the jQuery validation message in the final td cell of the table

JavaScript Animation Library rules:{ gender: { required: true }, }, messages:{ gender: { required: "Please indicate your gender" }, }, errorPlacement: function (error, element) { if (element.attr("type") == "radio") { ...

Vue.js encountered an uncaught TypeError while trying to execute the 'drawImage' function

I am facing an issue with my vue.js application where I can successfully apply a filter to a photo, but I am unable to post it. The error message I am encountering is: Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingCon ...

Mongoose fails to carry out internal query using Promise mechanism

Just diving into the asynchronous and await world, I decided to play around with Mongoose + MongoDB + Node.JS. Here is a snippet of my code: exports.updateBrandPreferences = async (req,res) => { var userID = req.body.playerID; var newBrands = r ...

What could be preventing me from successfully calling the JavaScript AJAX function in this particular situation?

Here is my code snippet from a smarty template: <form name="transaction_form" id="transaction_form"> <table class="trnsction_details" width="100%" cellpadding="5" > <tbody> <tr> ...

Placeholder variable not specified in radio buttons

I am currently facing challenges applying validations to radio buttons in Angular. Normally, I create a #templateRefVariable on the input for other input types, which allows me to access the NgControl and use properties like touched. My goal is to set the ...

Arrange the array depending on the existence of properties in the objects

Is there a way to efficiently organize an array like the following in cases where certain fields are missing? For instance, consider the current array: const users = [ { id: 1, firstname: 'Jerry' }, { id: 2, firstname: & ...

Repairing the Left-sided Popup Leaflet

Can someone help me with fixing the positioning of the Popup to the left of the map? Currently, it does not stay aligned to the left edge when moving the map. I tried using position: fixed in my styling, and while everything looks good when zooming, it br ...

Angular, perplexed by the output displayed in the console

I'm completely new to Angular and feeling a bit lost when it comes to the console output of an Angular app. Let me show you what I've been working on so far! app.component.ts import { Component } from '@angular/core'; @Component({ ...

Toggle the checkbox to update the count

I am trying to implement a feature where the user can check a maximum of 4 checkboxes. I have managed to achieve this functionality in the code below. When the user unchecks a box, the count should decrease by one and they should be able to check another c ...

Unlock the secrets of creating an interactive chat room effortlessly by harnessing the power of J

In search of implementing a unique chat room using PHP and JavaScript (Jquery) offering group chat as well as private chat functionalities. The challenge lies in finding a way to continuously update the interface seamlessly, while also displaying 'X ...

Can you explain the mechanics behind the animation of the upvote button on steemit.com?

Behold the upvote button of steemit.com: <span class="Icon chevron-up-circle" style="display: inline-block; width: 1.12rem; height: 1.12rem;"> <svg enable-background="new 0 0 33 33" version="1.1" viewBox="0 0 33 33" xml:space="preserve" xmlns=" ...