1

Hello all,

I have an issue with data binding. I am using the angulat boostrap modal to send a post request to a Laravel API and I am receiving the proper information. I am pushing the result in an array, the array is updated but the DOM isn't.

Can you please point me in the right direction?

This is the form I'm using in the modal:

<div class="container" ng-controller="ProjectsController">
<div class="row title">
    <h2>Project Info <small>Please fill in all the fields</small></h2>
</div>
<div class="row">
    <form ng-submit="createProject()">
        <div class="form-group">
            <!-- <label for="project-name" class="col-sm-2 control-label">Project name:</label> -->
            <div class="col-sm-12">
                <input type="text" name="name" id="project-name" class="form-control" placeholder="Project name" ng-model="new_project.name" required>
            </div>
        </div>
        <div class="form-group">
            <!-- <label for="project-name" class="col-sm-2 control-label">Project name:</label> -->
            <div class="col-sm-12">
                <textarea name="description" id="project-description" class="form-control" rows="3" placeholder="Project description"  ng-model="new_project.description" required></textarea>
                <!-- <input type="text" name="description" id="project-description" class="form-control" placeholder="Project description"  ng-model="new_project.description" required> -->
            </div>
        </div>
        <div class="form-group">
            <div class="pull-left">
                <button type="submit" class="btn btn-primary" ng-click="ok()">Submit project</button>
            </div>
            <div class="pull-left">
                <button type="submit" class="btn btn-primary" ng-click="cancel()">Cancel</button>
            </div>
        </div>
    </form>

This is where I want to update the DOM and where I trigger the dialog

<div class="create-proj" ng-controller="ProjectsController">
        <button id="saveProfileButton" class="primaryButton" ng-click="createModalNewProject()">Create Project</button>
    </div>
<ul class="projects" ng-controller="ProjectsController">
                <li ng-repeat="project in Projects">
                    <ul>
                        <li>
                            <h4><span class="title" ng-bind="project.name"></span>
                                <span class="dropdown left-navigation-project-settings-icons dropdown-toggle" data-toggle="dropdown"></span>
                            </h4>
                        </li>
                    </ul>
                </li>
            </ul>

This is the controller in angular:

angular.module('app.dashboard.projects')
    .controller("ProjectsController", function($scope, $modal, $resource, ProjectsFactory){
        $scope.Projects = {};
        $scope.new_project = {};

    $scope.createModalNewProject = function(){
        // console.log("bla");
        var modalInstance = $modal.open({
            templateUrl: 'js/modules/projects/views/new-project.html',
            controller : ModalController
        });
    };

        $scope.createProject = function () {
            ProjectsFactory.create($scope.new_project).$promise.then(function(data){
                $scope.Projects.push(data.projects);
            });
        };

        $scope.updateList = function(){
            $scope.Projects.push(data.projects);
        };



        showAll();
        function showAll(){
            ProjectsFactory.show().$promise.then(function(data){
                return $scope.Projects = data.projects;
            });
        };
    });

This is the factory that I'm using:

angular.module('app.dashboard.projects')
    .factory('ProjectsFactory', function ($resource) {
        return $resource('api/v1/projects/:projectId', {}, {
            show: { method: 'GET' },
            create: { method: 'POST' },
            update: { method: 'PUT', params: {id: '@id'} },
            delete: { method: 'DELETE', params: {id: '@id'} }
        })
    });

Reference to the modal module: http://angular-ui.github.io/bootstrap/

3
  • I think the first segment of code is not what you meant to paste there (as it's basically the same as the second and doesn't correspond with the header). Additionally adding a JSFiddle might help people investigate the problem. Commented Feb 10, 2014 at 18:18
  • Just to check when you do $scope.Projects.push(data.projects); is data.projects one project or an array? And is $scope.Projects an array of projects? -- Actually, you've initialized $scope.Projects = {}; What are you doing pushing stuff onto an object? Commented Feb 10, 2014 at 18:21
  • @towr, you were right. I edited the post because I missed some pieces of code. Commented Feb 10, 2014 at 20:26

3 Answers 3

1

The reason why data are not updated is because modal is isolated scope and you don't pass the data to the modal scope. Example how you can solve it:

angular.module('app.dashboard.projects')
    .controller("ProjectsController", function($scope, $modal, $resource, ProjectsFactory) {
        $scope.createModalNewProject = function() {
            var modalInstance = $modal.open({
                templateUrl: 'js/modules/projects/views/new-project.html',
                controller: function($scope, $modalInstance, items) {
                    $scope.items = items;

                    console.log($scope.items);
                    $scope.ok = function() {
                        $modalInstance.close();
                    };

                    $scope.cancel = function() {
                        $modalInstance.dismiss('cancel');
                    };
                },
                resolve: {
                    items: function() {
                        return ProjectsFactory.show().$promise.then(function(data) {
                            return data;
                        });
                    }
                }
            });
        };
    });
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for the idea. Unfortunately it doesn't update the DOM and the scope variable. Can you please take a look once more?
Hi here is an example and it works: plnkr.co/edit/fCfvcnwP9JSHbX5L2Vuu?p=preview
Hello. Thank you for the example. I actually need the response from the resource outside the dialog.
Can you create your example in plnkr ? So i can modify for you.
1

After some digging I changed the controller and now it looks like this. I forgot to broadcast the response from my ajax call so I can show it outside the modal scope. Thank you for all your help.

var CreateController = function($scope, $modalInstance, items,ProjectsFactory, $rootScope ){

    $scope.new_project = {};
    $scope.ok = function() {
        $modalInstance.close();
    };

    $scope.cancel = function() {
        $modalInstance.dismiss('cancel');
    };

    $scope.createProject = function (items) {
        ProjectsFactory.create($scope.new_project).$promise.then(function(data){
                if(data.error){
                    $rootScope.$broadcast('project.update', data.result);
                }
                $rootScope.$broadcast('project.update', data.result);
        });
    };
};

app.controller("ProjectsController",['$scope','$modal','$resource','ProjectsFactory','$timeout','$rootScope', function(
        $scope,
        $modal, 
        $resource,
        ProjectsFactory,
        $timeout,
        $rootScope
){

    $scope.Projects = [];

    $scope.$on('project.update', function(event, data) {
        $scope.Projects.unshift(data);
    });

    function showAll(){
        ProjectsFactory.show().$promise.then(function(data){
            $scope.Projects = data.result;
        });
    }

    showAll();

    // $scope.addProject = function(){
    //     $scope.Projects = $rootScope.Projects;
    //     $timeout(function(){$scope.$apply()},500);
    // }

    $scope.createModalNewProject = function(){
        var modalInstance = $modal.open({
            restrict: 'E',
            templateUrl: '/js/modules/projects/views/new-project.html',
            controller: CreateController,
            resolve: {
                items: function() {
                    return ProjectsFactory.show().$promise.then(function(data) {
                        return data.result;
                    });
                }
            }

        });
    };


    $scope.safeApply = function(fn) {
        var phase = this.$root.$$phase;
        if(phase == '$apply' || phase == '$digest') {
            if(fn && (typeof(fn) === 'function')) {
                fn();
            }
        } else {
            this.$apply(fn);
        }
    };


}]).controller('CreateController',['$scope','$modalInstance','items','ProjectsFactory','$rootScope',CreateController]);

Comments

0

I think the flow is wrong, In your controller do something like this

angular.module('app.dashboard.projects') .controller("ProjectsController", function($scope, $modal, $resource, ProjectsFactory) { $scope.Projects = ProjectsFactory.get(); }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.