Angular view fails to update after form submission when using ngDialog to change the scope

After starting my Angular journey, I decided to challenge myself by creating a comprehensive todo app for educational purposes. I seem to be missing something pretty basic, although I can't quite put my finger on it. It seems like there might be an issue with how I've set up my controllers and templates. Despite trying some suggestions from similar queries, none have resolved my problem. Even attempting to use $scope.$apply() leads to the dreaded "apply/digest already in progress" error.

My setup involves ngRoute so that when a user visits /profile, it triggers the profileController and loads templates/profile.html. The sole purpose of this controller is to establish the current user and attach to $rootScope. Within the profile view, I've included a nested controller named listController. This controller receives the List resource to handle HTTP requests. Everything appears to function correctly regarding routing and GET/POST requests.

Below, I've provided a simplified version of my controller:

var myApp = angular.module('todo', ['ngRoute', 'ngResource'])
    // config stuff...
    .controller('listController', ['$scope', 'List', 'ngDialog', function ($scope, List, ngDialog) { 
        // Fetches all lists associated with the current user
        $scope.lists = List.query();

        // Function to open modal form
        $scope.openModal = function () {
            ngDialog.open({
                template: 'templates/partials/new-list.html',
                className: 'ngdialog-theme-default'
            });
        };

        $scope.createList = function () {
            List.save({}, {
                name: $scope.list.name,
                description: $scope.list.description
            }).$promise.then(function(result) {
                $scope.lists.push(result);
            });
        };
    }]);

The snippet below represents the relevant section of templates/profile.html, which successfully displays all lists fetched using List.query():

<div class="todo-sidebar" ng-controller="listController">
    <h3>Your lists <a href="#" ng-click="openModal()"><span>New list</span></a></h3>
        <ul>
            <li ng-repeat="list in lists">
                <a href="#"><span class="list-name">{{list.name}}</span></a>
        </li>
    </ul>
</div>

The issue arises when I invoke the createList function from the templates/partials/new-list.html partial:

<div class="dialog-contents" ng-controller="listController">
    <h3>New list</h3>
    <form ng-submit="createList()">
        <div class="form-group">
            <label>Name</label>
            <input type="text" name="name" ng-model="list.name">
            <textarea name="description" ng-model="list.description" rows="10"></textarea>
            <button type="submit" class="button">Create list</button>
        </div>
    </form>
</div>

While the form submission works flawlessly and adds the new list to the database, the view doesn't update in real-time. Upon inspecting with console.log($scope) within the promise block, it's apparent that the new list does get appended to the scope.

I suspect that attaching a controller to multiple elements/templates may not be best practice, but I'm unsure about alternative structuring options.

Answer №1

After conducting some research, I believe I have found a solution to your issue. It appears that the problem lies in how you are handling the closure of the dialog box.

Below is the link that I referred to during my research:

https://github.com/likeastore/ngDialog#api

Scope Problem

The issue at hand seems to be related to scope. When the dialog box opens, it creates a separate module with its own controller. This controller's scope is one-way bound and cannot be accessed by the parent scope when the dialog resolves. This explains why your scope is not updating at the parent level.

For more information on resolving this issue, please refer to the section about promises.

Promise Solution

To manage the scope at the parent level, you will need to use a promise function. This function executes after the dialog closes completely. By utilizing the promise function, you can pass data and update the parent-level scope variables accordingly.

I have provided updated code below that may assist you in addressing this problem:

var myApp = angular.module('todo', ['ngRoute', 'ngResource'])
// config stuff...
.controller('listController', ['$scope', 'List', 'ngDialog', function ($scope, List, ngDialog) { 
    // Retrieve all lists for the current user
    $scope.lists = List.query();

    // Function to open modal form
    $scope.openModal = function () {
        var dialog = ngDialog.open({
            template: 'templates/partials/new-list.html',
            className: 'ngdialog-theme-default',
            controller : function($scope){  
                $scope.createList = function(){
                    dialog.close($scope.list); // Pass list data when closing dialog
                };
            }
        });
        dialog.closePromise.then(function(data){
            // Update value based on data passed from dialog closure
            List.save({}, {
               name: $scope.list.name,
                description: $scope.list.description
            }).$promise.then(function(result) {
               $scope.lists.push(result);
            });
        });
    };
}]);

This code serves as a general guideline for implementing the solution. Feel free to reach out if you require further clarification or assistance. Good luck!

Answer №2

It seems like you may be experiencing a $scope issue. While the values are present, it appears that you're not referencing them correctly. Try accessing the "lists" using controllerAs, as shown below:

<li ng-repeat="list in MyController.lists"> 

This adjustment should resolve your issue.

I hope this solution proves helpful to you. For a more in-depth explanation, you can also refer to this resource: https://github.com/angular/angular.js/wiki/Understanding-Scopes#ngRepeat

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

Having trouble retrieving JSON data using ajax

I am currently working with JSON data that is being generated by my PHP code. Here is an example of how the data looks: {"Inboxunreadmessage":4, "aaData":[{ "Inboxsubject":"Email SMTP Test", "Inboxfrom":"Deepak Saini <*****@*****.co.in>"} ...

Having trouble with the JSON format within the 'operations' field in the formData of your Next.js application?

I encountered a mutation that looks like this- mutation signUp($avatar: Upload!) { signUp( avatar: $avatar input: { name: "Siam Ahnaf" email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail= ...

Is there a way to reduce the excessive bottom margin on Twitter embeds?

Is there a way to adjust the Twitter embed code for tweets so they don't have a large margin at the bottom? Here is an example of the standard Twitter embed code: <blockquote class="twitter-tweet"><p>@<a href="https://twitter.com/gami ...

Guide on how to dynamically add AJAX JSON array response to an HTML table

Hey! I need some advice on how to dynamically append a JSON Array response to an HTML table after submitting a form using AJAX. Here's the scenario: This is my form : <form id="myForm" method="POST"> <input type=" ...

Troubles with AJAX comment system validation issues

Having created a webpage that displays articles with a textarea under each article for user comments, I implemented AJAX successfully. The validation also works fine - if the textarea is empty, it will display an error and not submit the comment. However, ...

Generating Bootstrap Vue Dropdown components in real time

I am currently utilizing Bootstrap Vue to construct a dynamic Dropdown component that can render different elements such as item, title, and divider. Is there a method to accomplish this task effectively? The desired outcome for the Dropdown component wou ...

Getting a page element by its id with QWebEngineView is a simple task that can be

Is there a way to access the page ElementById in order to input a value? import sys from PyQt5 import QtWebEngineWidgets from PyQt5.QtCore import * from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import * from PyQt5.QtWidgets import QAction from PyQt ...

Using Promise.map inside another Promise.map

Attempting to return a JSON object via Bluebird's Promise.mapSeries/Promise.map nested within another Promise.mapSeries/Promise.map is proving difficult. Below is the code snippet for the function: function getMovieDetails(link){ return new Promise(f ...

Optimal method for managing errors in Flask when handling AJAX requests from the front end

I'm currently working on a React application that communicates with a Python Flask server. One of the features I am adding allows users to change their passwords. To do this, an AJAX request is sent from React to Flask, containing both the old and ne ...

A guide to organizing page components across multiple `/pages` directories in a Next.js application

As I delve into my first project using Next.js, I find that my pages directory has expanded significantly. Now, I am keen on organizing my pages by grouping them into modules, resulting in a structure like 'src/modules/*/pages/*'. In my quest fo ...

JEST does not include support for document.addEventListener

I have incorporated JEST into my testing process for my script. However, I have noticed that the coverage status does not include instance.init(). const instance = new RecommendCards(); document.addEventListener('DOMContentLoaded', () => ...

Contrasting $interval and setInterval functions in AngularJs

I am trying to grasp the distinction between $interval and setInterval. I have come up with this test: Dashboard.prototype.updateTotalAppointments = function(){ //console.log(); this.appointmentsCount = this.appointmentsCount +1; console.log(this.appointm ...

How can you refresh the .replaceWith method in jQuery?

Is there a way to reset the .replaceWith function so that the html, css and javascript elements are restored to their original state? I am looking to have an icon replace the text when the user clicks on "contact", and then have the text return when the u ...

Can someone guide me on implementing Node.js clusters in my basic Express application?

— I have successfully developed a basic application that retrieves data (50 items) from a Redis DB and displays it on localhost. After running an ApacheBench test with parameters c = 100, n = 50000, I am achieving around 150 requests/sec on my aging dual ...

Access an object's property from within a callback function

I have an async.series() function that is calling a method from another Javascript object: main.js var obj1 = require('./obj1'); var obj2 = require('./obj2'); async.series([ obj1.myFunc1, obj2.anotherFunc ]); obj1.js module ...

There seems to be a problem with the sorting functionality on the table in React JS,

My React table is functioning well with all columns except for the country name column. I double-checked the API and everything seems to be in order, but I'm stuck on how to troubleshoot this issue. const Table = () => { const[country, setCount ...

After running the Grunt build, the Angular call to PHP results in a 404

I'm really in need of some guidance here, as I'm quite lost building my first ng-app. The issue lies with the Grunt build results where the api calls (php) are not being found. My folder structure consists of dist->api->index.php, so it's p ...

Tips for changing the size and color of SVG images in a NextJS application

Looking to customize the color and size of an svg image named "headset.svg". Prior to this, I used next/image: <Image src={'/headset.svg'} alt='logo' width={30} height={30} className='object-contain' /> The s ...

What is the best way to stop Quasar dropdown list from moving along with the page scroll?

I am facing an issue with my code while using Quasar (Vue 3.0). The code snippet in question is: <q-select filled v-model="model" :options="options" label="Filled" /> When the drop-down menu is open and I scroll the pag ...

Encountering a 404 error when trying to reload the page?

My React Router is functioning properly in the development environment. Here's what I implemented in Webpack Dev Server: historyApiFallback: { index: 'index.html', } Now, when transitioning to production mode, I wanted to replicate the ...