Passing a parameter to an AngularJS directive, which triggers the opening of an ngDialog, and subsequently updating the value to reflect changes in the root scope

Struggling with a persistent issue here; Essentially, I have a directive that triggers an ngDialog to open. This directive should be able to receive a variable from the root scope. The directive contains a click event that opens an ngDialog which then uses the passed-in value to populate a textbox... but updates made in the textbox within the ngDialog are not reflecting back on the root scope.

The Challenge The variable being passed does not maintain its link to the rootscope. Updates in the ngDialog don't propagate back to the root scope and I suspect I've overlooked something fundamental. Any assistance would be greatly appreciated.

//HTML Snippet

<b>Instructions: </b>Click on the blue items to open ngDialog<br /><br />
<div ng-controller="MyCtrl">
    <b>Base $scope.variable1 = </b> {{variable1}}
    <span pass-object passed-object="variable1"></span><br />
    <b>Base $scope.variable2 = </b> {{variable2}}
    <span pass-object passed-object="variable2"></span><br />
    <b>Base $scope.variable3 = </b> {{variable3}}
    <span pass-object passed-object="variable3"></span><br />
</div>

//JavaScript Code

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

myApp.controller('MyCtrl', function ($scope) {
    //Defining 3 scope variables
    $scope.variable1 = "value 1";
    $scope.variable2 = "value 2";
    $scope.variable3 = "value 3";
});

//Creating a directive for opening an ngDialog that can accept and update a scope variable within it
myApp.directive('passObject', ['ngDialog', function(ngDialog) {
    return {
        restrict: 'A',
        scope: { passedObject: '=' },
        template: "<div class='directive'>This directive's received value is = {{passedObject}}!</div>",
        link: function($scope, element){
            element.on('click',function(){
                ngDialog.open({
                    template: '<div>I want changes in this textbox to reflect in root scope:<br /><br />' + 
                              '<input type="text" ng-model="passedObject"/></div>',
                    plain: true,
                    scope: $scope,
                    controller: ['$scope', function($scope){
                        $scope.$watch('passedObject', function(passedObject){
                            //Need to figure out why changes at this level aren't propagating upwards
                            alert('updated with: ' + passedObject);
                            $scope.$apply();
                        });
                    }]
                })
            });
        }
    };
}]);

//Check out the Fiddle for reference

http://jsfiddle.net/Egli/od8a2hL0/

//Many Thanks :D

We appreciate any help offered

Answer №1

When you encounter the error message "the console says $digest already in progress, just remove the $scope.$apply();"

Here is a helpful link: http://jsfiddle.net/usmoetyd/

To avoid this issue, it is recommended to use objects instead of primitive types in your AngularJS controller:

myApp.controller('MyCtrl', function ($scope) {
    // Let's say I have 3 scope variables
    $scope.variable1 =  { value : "value 1" };
    $scope.variable2 =  { value: "value 2" };
    $scope.variable3 =  { value: "value 3" };
});


// If you need to pass a scope variable into a directive and update it from within ngDialog, consider using an object.
myApp.directive('passObject', ['ngDialog', function(ngDialog) {
    return {
        restrict: 'A',
        scope: { passedObject: '=' },
        template: "<div class='directive'>This is the value passed into this directive = {{passedObject.value}}!</div>",
        link: function($scope, element){             

            element.on('click',function(){             
                ngDialog.open({
                    template: '<div>By updating I need it to reflect in the root scope:<br /><br />' + 
                              '<input type="text" ng-model="passedObject.value"/></div>',
                    plain: true,
                    scope: $scope,
                    controller: ['$scope', function($scope){
                        $scope.$watch('passedObject', function(passedObject){
                            // Make sure to update the parent scope when changing the object at this level
                            console.log(passedObject);                                
                        });
                    }]
                })

            });
        }
    };
}]);

For more examples, visit: http://jsfiddle.net/jyk6Lbwe/1/

If you want to dive deeper into AngularJS prototypal inheritance, check out this informative Stack Overflow thread: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

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

Easily toggle between different content within the same space using Twitter Bootstrap Tabs feature. Display the tabs

I made a modification to the bootstrab.js file by changing 'click' to 'hover': $(function () { $('body').on('hover.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { e.p ...

What are some ways I can improve the readability of this if-else function in Javascript ES6?

As a newcomer to React development, I am currently in the process of tidying up my code. One issue that I am facing is how to deal with a particular function while minimizing the use of if-else statements. const calculatePerPage = () => { if ...

Enhance Image Size with a Custom React Hook

I've created a function to resize user-uploaded images stored in state before sending them to the backend. const [file, setFile] = useState(null) function dataURLtoFile(dataurl, filename) { let arr = dataurl.split(','), mime = arr[0].ma ...

Encountering issues with proper function of history.listen within React Router

I am struggling to get my function to work every time React detects a change in the URL. The history.listen method is not triggering (the console.log statement is not showing up). I have read that this issue may be related to using BrowserRouter, but when ...

Replacing values in an HTML file with MySql query results

----- Problem solved, solution below ----- In my HTML file, I have a dropdown menu for various courses listed as follows: <ul> <li class="dropbtn" id="1"> <a href="">first</a> <ul class="dropdown-content"> ...

The process of incorporating or expanding an object within a component

When using vue.js, you have the ability to iterate over an array of items in your template as shown below: <div id="app"> <div v-for="(item, i) in items">i: item</div> </div> <script> var example2 = new Vue({ el: &ap ...

Is it possible to utilize Angular JS without utilizing a terminal interface?

Every time I try to work with the terminal, git, and other tools, my learning curve goes through the roof as I attempt to build an app quickly using CodeIgniter. I understand the importance of a JavaScript framework like AngularJS - is there a way to avo ...

Eliminating empty elements from arrays that are nested inside other arrays

I am facing a challenge with the array structure below: const obj = [ { "description": "PCS ", "children": [ null, { "name": "Son", ...

Tips for monitoring events emitted through $scope.$broadcast

Help needed with angular-timer events tracking. Specifically, I am unsure how to monitor and respond to events such as when the timer is up. Even after trying to log events to the console, there seems to be no output. vm.add20Seconds = function() { ...

Utilizing asynchronous operations in MongoDB with the help of Express

Creating a mobile application utilizing MongoDB and express.js with the Node.js MongoDB driver (opting for this driver over Mongoose for enhanced performance). I am aiming to incorporate asynchronous functions as a more sophisticated solution for handling ...

The art of transforming properties into boolean values (in-depth)

I need to convert all types to either boolean or object type CastDeep<T, K = boolean> = { [P in keyof T]: K extends K[] ? K[] : T[P] extends ReadonlyArray<K> ? ReadonlyArray<CastDeep<K>> : CastDeep<T[P]> ...

Transform Material UI Typography to css-in-js with styled-components

Can Material UI elements be converted to styled-components? <Container component="main" maxWidth="XS"> <Typography component="h1" variant="h5"> Sign in </Typography> I attempted this for typography but noticed that t ...

Utilizing AngularJS and RequireJS to incorporate a controller into the view

I am facing an issue while trying to add an Angular controller to my HTML view. Typically, in Angular, this can be done using: ng-controller="<controller>". However, due to my use of RequireJS, I have had to implement it differently. I need to includ ...

Step-by-step guide for integrating a Twig file in Symfony using Angular's ng-include feature

Seeking guidance in Angular, as a newcomer to the platform. I attempted to load a template within an ng-repeat loop like so, but encountered an error. I received the following error message: "Cross origin requests are only supported for protocol schemes ...

What is the best way to showcase the array data of two description values in a Vue v-for loop?

An array called ledgerDetails contains 32 data elements. These details are displayed in a vue v-for loop. However, within the loop, I need to show specific details from invoiceDescriptions (23 data elements) and paymentDescriptions (1 ...

Analyzing latency in node.js through numerous requests

Is there a way to send multiple requests in a loop, and measure the time of each request? In PHP I'd do: require 'vendor/autoload.php'; use GuzzleHttp\Client; $client = new Client(); for ($i = 0; $i < 100; $i++) { $start = mic ...

Tips for assigning a class name to a variable element within a react component?

I am interested in dynamically adding classes to an element. While I am familiar with methods using html-dom and passing a JavaScript expression to className, I am seeking a different approach. Is there a way to add classes similar to pushing them to an ar ...

What is the procedure for utilizing the comparator to arrange items according to various attributes?

I am trying to find a way to arrange my models in a collection based on their required flag and then alphabetically by their value. This is what my current code looks like: var myModel = Backbone.Model.extend({ defaults: { required: true, ...

The color input click event does not work properly when triggered within a context menu event

This may sound a bit complicated, but let me try to explain it clearly. I'm working on a web app where I want users to be able to change the background color of certain divs. I plan to use a color picker interface for this purpose and utilize the con ...

Converting HTML tables into arrays

I have JSON content that needs to be transformed into an array, specifically from a HTML table with cell values. Those cells should be combined into a single array for further use in the project. Struggling with the conversion of cell values into an arra ...