Set up input fields for text within an Angular directive

Trying to initialize input fields in a directive with server data, but facing issues with ng-model. Previously used $scope.field1 = $scope.first.field1 in the controller before using directive.

Code simplified for readability:

In controller:

app.controller('MyController',
    ['$scope', 'myData', function($scope, myData) {
        myData.then(function(data) {
            $scope.first = data.first;
            $scope.second = data.second;
        });
}]);

First and second fields: field1 and field2.

In HTML code:

<h1>First</h1>
<my-directive info="first"></my-directive>
<h1>Second</h1>
<my-directive info="second"></my-directive>

Directive:

app.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: {
            info: '='
        },
        templateUrl: 'static/js/myDirective.html',
        link: function(scope, element, attrs) {
            scope.doStuff = function() {
                /* Do stuff with 
                scope.field1 and scope.field2 */
            }
        }
    };
});

myDirective.html:

<input type="text" ng-model="myfield1" />
<input type="text" ng-model="myfield2" />
<input type="submit" ng-click="doStuff()" />

If using:

<input type="text" value="info.field1" />

The value shows up successfully.

Looking for ideas to resolve the issue.

Answer №1

It seems like your directive is initializing before your data loads, causing it to see ng-model as an undefined variable. Since you are not using info directly in the template, there are no auto $watch functions available for you.

You need to implement a $watch on the info variable in the directive and trigger your doStuff function when it changes.

Keep in mind that adding a controller to a directive just for this purpose is not recommended. Controllers in directives should be used for communication with other directives, not for handling asynchronous data loading.

Here's how you can update your directive:

app.directive('myDirective', function() {
return {
    restrict: 'E',
    scope: {
        info: '='
    },
    templateUrl: 'static/js/myDirective.html',
    link: function(scope, element, attrs) {
        scope.doStuff = function() {
            /* Do stuff with 
            scope.field1 and scope.field2 */
        }
        scope.$watch('info', function(newValue){
            scope.doStuff();
        });
    }
};
});

Answer №2

To see a live demonstration, click here: Live Demo.

Create a controller specifically for the directive and handle all initialization tasks within it:

app.directive('myCustomDirective', function() {
    return {
        restrict: 'E',
        scope: {
            data: '='
        },
        controller: ['$scope', 'customService', function ($scope, customService) {
           customService.getData().then(function(response){
               $scope.property1 = response.property1;
               $scope.property2 = response.property2;
           });
        }],
        ...
    },

Answer №3

When working inside the directive, you might notice that myfield1 and myfield2 are not present. To resolve this issue, consider using info.field1 instead.

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

//Mocking myData here; in your case, this data would be fetched from the server
var myData = {
    first: {
        field1: "FirstField1",
        field2: "FirstField2"
    },
    second: {
        field1: "SecondField1",
        field2: "SecondField2"
    }
};

myApp.controller('MyController', ['$scope', function($scope) {
    $scope.first = myData.first;
    $scope.second = myData.second;
}]);

myApp.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: {
            info: '='
        },
        template: '<input type="text" ng-model="info.field1" /><input type="text" ng-model="info.field2" /><input type="submit" ng-click="doStuff()" />',
        link: function(scope, element, attrs) {
            scope.doStuff = function() {
                alert('Info: ' + scope.info.field1 + ', ' + scope.info.field2);
            }
        }
    };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>

<div ng-app="myApp" ng-controller="MyController">
    <h1>First</h1>
    <my-directive info="first"></my-directive>
    <h1>Second</h1>
    <my-directive info="second"></my-directive>
</div>

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

Obtain data transmitted via POST method from JavaScript to PHP

When working with Javascript and JQuery, I am sending an object via post in the following manner: var myobj = {}; myobj['test'] = 1; myobj['child'] = {}; myobj['child']['test2'] = 2; var myvar = 123; $.ajax({ type ...

Validating HTML Forms

By incorporating an internal JavaScript function like the one shown below: <script> function validateForm() { var x=document.forms["myForm"]["firstName"].value; if (x==null || x=="") { document.getElementById('usernameError& ...

Incorporating a new div element into a CSS layout with multiple

Could this be done? Imagine I have 15 divs, with 3 in each of the 5 columns of a multiple column CSS layout. I also have responsive code that adjusts the number of columns based on screen size. So, is there a way to insert a div between the 12th and 13th ...

"Exploring the method of aggregating markers into a single point when zoomed out using Google Maps API

My web app features a Google Maps view. I have designed custom markers with unique info views for each one. As users zoom out, I want to avoid cluttering the map with numerous individual markers. Instead, I would like to group them together with a number ...

Customize your application with Kendo UI localization features

Is there a more efficient way to localize a front-end application that utilizes a framework like Kendo UI? For example, you can start by dynamically changing text using JavaScript: $(document).ready(function(){ $("#myText").html(<grab text based on ...

The desktop menu disappears off the screen when attempting to hide it on a mobile device

My website has two menus, one on the left and one on the right, along with a search bar. When the user activates the menus, they smoothly slide in from the edge of the screen as intended. However, I encountered an issue where the right menu slides off the ...

There are no headers present in the response from apollo-client

I am currently utilizing a graphql api along with a vue.js frontend that incorporates the apollo client for fetching data from the backend. This setup has been operating smoothly thus far. In each response header, the server sends back a new JWT-Token whi ...

Struggling to figure out a basic Javascript function for calculating height

Does anyone have any ideas as to why this code isn't working properly? I am trying to set a dynamic height for a fixed width div that might extend below the viewport. <script type="text/javascript"> function adjustHeight() { var div = docum ...

The useEffect hook will not trigger a re-call of the function passed as a prop

I am facing an issue with a function that I am passing to my reusable component as a prop. This function is responsible for generating and returning two random numbers along with their addition result. While everything works fine initially, I am struggling ...

The three.js texture is not displaying properly as it appears black on the screen

I am currently working on a project that involves creating a simple scene with a plane that has a texture applied to it. For reference, here is the code I am using: https://jsfiddle.net/0w6vfLt4/1/ The issue I am facing is that despite everything else fu ...

Ways to change the visibility of a view depending on a state in vuex?

If I have a button <Button> Log me in! </Button>, and I want to dynamically change its style based on the state of my Vuex app (state.user is not null). How should I properly implement this functionality? I'm considering creating a field ...

Storing multiple email addresses in an array using an HTML input element

I have a small React Bootstrap form where I am trying to save multiple email addresses entered by the user into an array. However, when I use onChange={()=> setEmails(e.target.value as any} it stores them in string format like this --> [email p ...

Ever attempted to display a unique custom shape like a rhombic dodecahedron using Three.js?

Is there a way to render this shape? Unfortunately, my attempt at creating a custom mesh failed and resulted in an error. I found some old THREE.js code that partially solves the problem, but it relies on the deprecated THREE.Face4() method. After consul ...

Is it possible for me to retrieve/load a <datalist> element from a different file?

I'm in the process of developing a Google Chrome extension that essentially consists of a dropdown menu and an input box with datalists. The user can change their selection in the dropdown menu, which will then switch the datalist being used by the in ...

Empty req.body in Node.js when POST method is used

I'm completely new to exploring REST and Express, and I've been following this insightful tutorial on creating a REST API. Here's a glimpse of my programming journey through the lens of my app.js code: var express = require('express&ap ...

Steps to duplicate a Select input and attach it to a div using Jquery

Recently, I was working on a Select input with the name "item" as an example. <select name="item"> <option value="1">1</option> <option value="2" selected="selected">2</option> <option value="3">3</option> <opt ...

How can we detect line breaks within a selection using JavaScript?

Apologies for the lack of expertise in the content below, as it is being produced by a designer experimenting with coding :D The goal here is to determine the number of lines selected or highlighted by the cursor. When I mention "lines," I mean what is vi ...

Web application's caching problem caused by the use of ReactJS and webpack

Currently, I am working on a web application that is built with reactjs and webpack. However, after each deployment, we are encountering the issue of users having to clear their browser cache and restart their browsers. It seems like both the javascript bu ...

Trouble encountered while sending registration data within redux-saga

Having an issue within the redux-saga workflow when trying to register a single user. Below is the relevant code snippet for the redux-saga: // Importing necessary modules import * as ActionTypes from "./constants"; import { signupAPI } from "../../../uti ...

Transforming an array of HTTP Observables into an Observable that can be piped asynchronously

I am attempting to execute a series of XHR GET requests based on the results of an initial request. I have an array of observables representing the secondary requests I wish to make, and I am able to utilize Array.map for iterating over them and subscribin ...