AngularJS Two way data binding - angularjs

In my controller I have the following data:
(function() {
'use strict';
angular
.module('myappl.mymodule')
.controller('MyController', MyController);
MyController.$inject = ['$scope', 'myService'];
function MyController($scope, 'myService') {
$scope.vm = this;
var vm = this;
vm.myService = myService;
vm.userManagement = userManagement.data;
vm.userManagementSomeDataObjects = vm.userManagement.someDataObjects;
Somewhere in this controller I have a function which first gets data from backend and than invoke showModal:
function modalForUserInteraction() {
vm.myService.getData(parameters).success(function(data) {
vm.modalService.showModal(data, vm.userManagement, vm.userManagementSomeDataObjects);
}).error(function(data) {
console.log('error');
});
}
The modal- controller looks like this:
...
function showModalService($modal, $stateParams, otherService) {
var service = {
showModal: showModal
};
return service;
////////////
function showModal(data, userManagement, userManagementSomeDataObjects) {
var myModal = $modal.open({
controller: ModalController,
controllerAs: 'vm',
windowClass: "modal fade in",
resolve: {
userManagement: function() {
return userManagement;
},
userManagementSomeDataObjects: function() {
return userManagementSomeDataObjects;
}
},
templateUrl: 'url/to.html'
});
return myModal;
and in the modal controller there is a method like this one:
function ModalController(userManagement, userManagementSomeDataObjects) {
var vm = this;
...
function doSomeActionAfterButtonClickAtModal() {
otherService.getDataFromBackend(params).success(function(data) {
userManagement = data;
userManagementSomeDataObjects = data.someDataObjects;
})error(function(data) {
console.log('error');
});
}
If I do it like this:
userManagement = data; and userManagementSomeDataObjects = data.someDataObjects; than the new data is not set.
If I set each property separately of the objects than it works more often than not but somethimes it does not.
My question now would be what I can do in order to get it work.
Currently I do not have a $scope- variable in my modal and actually I don't know
if $scopeOfModal.$apply() would help and I also don't know how to get access from modal to MyController - $scope.
I would be glad for any hint in this direction.
Thanks a lot!
[EDIT]
Here is an image of my currently viewed (right) an on the left side the object, which should be shown after setting in modal- function.
[EDIT]
is there any posibility to pass parameters to this function in the modal controller:
this.previewArchivedSchedule = function(hereINeedParamerts) {
alert('archivedScheduleIntervalContainerId: ' + hereINeedParamerts);
};

This looks to me just like it may have nothing to do with angular, just some confusion with javascript variable references.
First you pass userManagement from showModalService.showModal to ModalController via resolve.
So now ModalController has a reference to the same object as showModalService.
However, in ModalController, you reassign the userManagement variable to point to data instead. So now the userManagement variable inside ModalController isn't pointing at the injected object anymore, because you've reassigned it. This has nothing to do with angular two-way data binding, it's just javascript variable assignment. You've lost your reference to the original object.
showModalService still has a reference to the instance that it sent in via resolve, it has no idea that you swapped the reference out in the ModalController.
I'd try sending over an object encapsulating the data you want to share to fix this problem.
function showModal(data, userManagement, userManagementSomeDataObjects) {
var myModal = $modal.open({
controller: ModalController,
controllerAs: 'vm',
windowClass: "modal fade in",
resolve: {
sharedData: function() {
return {
userManagement: userManagement,
userManagementSomeDataObjects: userManagementSomeDataObjects
}
},
templateUrl: 'url/to.html'
});
return myModal;
Then manipulate the properties on the shared object instead of overwriting references.
function ModalController(sharedData) {
var vm = this;
...
function doSomeActionAfterButtonClickAtModal() {
otherService.getDataFromBackend(params).success(function(data) {
sharedData.userManagement = data;
sharedData.userManagementSomeDataObjects = data.someDataObjects;
})error(function(data) {
console.log('error');
});
}

Related

Pass data from modal to another page in angularjs

I need to pass data from modal to another page. Could you please help me to accomplish this task?
$scope.productdetails = function (size,selectedproduct)
{
var modalInstance = $uibModal.open({
templateUrl: 'ProductDetails.html',
controller: function ($scope, $uibModalInstance, product) {
$scope.product = product;
$scope.buynow = function (path) {
$uibModalInstance.close($scope.product);
$location.path(path); // Need to pass $scope.product to the new page
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
},
size: size,
resolve: {
product: function () {
return selectedproduct;
}
}
});
Be sure to read the docs on $uibModal: https://github.com/angular-ui/bootstrap/tree/master/src/modal/docs
the open() method will return an object with some useful stuff in it. Currently you're not doing anything with that object, but that's where the magic is.
To pass data to the controller that opened the modal, use the modalInstance.result promise like this:
modalInstance.result.then(function(data) { /*... do something with the data*/ });
Once that is set up, you can use the $close() function that this modal library places on the scope to resolve the result promise.
var data = {info: 'information to be returned to the parent controller'};
$scope.$close(data);

Angular ui router undefined function in controller

I have a ui route that looks like the following
.state('question', {
url: '/question',
templateUrl: 'views/templates/question.view.htm',
controller: 'QuestionController',
resolve: {
questions_preload: function(Question) {
return Question.query();
}
}
});
The Question.query() function looks like
Question.query = function () {
var deferred = $http.get(HATEOAS_URL);
return SpringDataRestAdapter.processWithPromise(deferred).then(function (data) {
Question.resources = data._resources("self");
return _.map(data._embeddedItems, function (question) {
return new Question(question);
});
});
};
and the controller that should have the questions preloaded at the start beings like this
angular.module('myapp').controller('QuestionController', function ($scope, Question) {
$scope.questions = questions_preload;
Unfortunately while the Question.query() method runs correctly the questions_preload which I figured would house the array is undefined when the controller executes.
I believe it's something to do with the deferred in the query function?
Would anyone have any idea?
Thanks,
Mark.
You have to inject the questions_preload value into your controller:
angular.module('myapp')
.controller('QuestionController',
function ($scope, Question, questions_preload) {
...
$scope.questions = questions_preload;
As you had it you were simply accessing an undefined variable.
The use of a promise in Question.query() doesn't matter here as angular ui-router will wait until the promise has resolved before it instantiates your controller.

Updating the $scope value

I wanted to display the added users dynamically in the dashboard.
My code is in the following way.
Controller: where the actual action triggers .
Adding the user function
$scope.addUser= function(){
modalService.addUser();
}
function init(){
// Someother functions
getUserRequests()
};
function getUserRequests() {
datacontext.getExtranetUserRequests()
.then(function (data){
vm.ExtranetUserRequest = data;
});
};
Service: modalService
addUser: function (column) {
var modalInstance = $modal.open({
templateUrl: 'app/NewExtranetSite/Popup/userModal.html',
controller: 'userModal',
});
updateUser: function(){
// updates the user
});
Controller :userModal
In the userModal.html after adding the info and on clicking save, add user function will be triggered.
function addUser(){
datacontext.saveNewExtranetuserRequest($scope.user);
};
I would like to initiate the getUserRequests() after the completion of add user in the user modal
So that the newly added user can be visble on the dashboard without refreshing the page
Let me answer u shortly.
You have a view where you are adding user details from input using one form ().
On ng-submit or ng-click action you can call one method in your that particular view's controller.
Now to display user details, you might know json. So create a blank $scope variable which will contain added user details.($scope.variable=[];)
Now on submit just hit **
$sope.variable.push({'key':value,'value':value});
**
once your object is populated with new data it will automatically displayed in the view.
5. We have just awesome ng-repeat angular's directive to show dynamical list containing objects.
6. **
ng-repeat="key in variable track by $index"
**
The $modal.open function returns a promise, so it's easy to wait for the modal to close and then execute another function. Let 'addUser' return this promise, then wait for it to finish before executing getUserRequests:
in modalService:
addUser: function (column) {
var modalInstance = $modal.open({
templateUrl: 'app/NewExtranetSite/Popup/userModal.html',
controller: 'userModal',
});
return modalInstance;
}
in controller:
$scope.addUser= function(){
modalService.addUser().then((resultReturnedFromModal) => {
getUserRequests();
});
}
Sorry for the bad post.
Let me explain briefly in this post
I would like to display the added data dynamically on the page.
I have a controller where the user addition action takes place.
(function () {
'use strict';
var controllerId = 'newUser';
angular.module('app').controller(controllerId,
['modalService', '$scope', 'dataContext', newUser]);
function newUser(modalService, $scope, dataContext) {
init();
function init() {
var extranetSiteRequestId = +$routeParams.id;
if (extranetSiteRequestId && extranetSiteRequestId > 0) {
getItem(extranetSiteRequestId);
getUserRequests();
}
}
$scope.newuserRequest = function () {
modalService.addUser();
}
function getUserRequests() {
datacontext.getExtranetUserRequests().then(function (data) {
vm.UserData = data;
});
};
}
}());
I am using a service modalService to handle the add user request.
(function (){
'use strict';
var serviceId = 'modalService'
angular.module('app').service(serviceId, ['$modal', modalService]);
function modalService($modal) {
return {
addUser: function () {
var modalInstance = $modal.open({
templateUrl: 'app/NewExtranetSite/Popup/userModal.html',
controller: 'userModal',
});
modalInstance.result.then(function (userDetails) {
if (userDetails) {
alert(userDetails) ;
};
})
},
};
}
})();
finally in the userModal controller am handling the new user added request
(function () {
'use strict';
var controllerId = 'userModal';
angular.module('app').controller(controllerId, ['$scope', '$modalInstance', 'datacontext', 'common', addUserModalFunction]);
function addUserModalFunction($scope, $modalInstance, datacontext, common) {
var vm = $scope;
vm.cancel = cancel;
vm.submit = addUser;
init();
function init() {
common.logger.log("controller loaded", null, controllerId);
common.activateController([], controllerId);
}
function cancel() {
$modalInstance.close();
}
$scope.open = function ($event, opened) {
$event.preventDefault();
$event.stopPropagation();
$scope[opened] = true;
};
function addUser() {
datacontext.saveNewExtranetuserRequest($scope.user).then(function(data){
$modalInstance.close($scope.user);
});
};
};
})();
Now the problem is I would like to add a success or then function in the newUser Controller after the modalService.adduser complete
EX: modalService.addUser().then(function(results){
});
Fikkatra Thanks for the reply but couldn't able to achieve
am very bad # angular

AngularJS Error: [$injector:unpr] Unknown provider:

I am getting an unknown provider error when attempting to launch an angular bootstrap modal window from my app by clicking on an image. I launch the same type of modal successfully elsewhere in the app.
Here is a screenshot of the error in the debugger
Is there something wrong with my controller code below? I looked at several other unknown provider error posts on stack, and to my knowledge I'm doing things properly.
app.controller('ModalInstanceCtrl', function($scope, $modalInstance, items,
removeVideoFromCart, removeLiteratureFromCart, productHasItems, cartItemHasVideos,
cartItemHasLiterature, getCartMailToBody, cartMailtoLink, logSentItems) {
$scope.items = items;
$scope.ok = function() {
$modalInstance.close($scope.test);
};
$scope.removeVideoFromCart = function (video, familyIndex, index) {
removeVideoFromCart(video, familyIndex, index);
$scope.cartMailtoLink = getCartMailToBody(); //update the mailto link body to remove video links
}
$scope.removeLiteratureFromCart = function (literature, familyIndex, index) {
removeLiteratureFromCart(literature, familyIndex, index);
$scope.cartMailtoLink = getCartMailToBody(); //update the mailto link body to remove lit links
}
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
$scope.productHasItems = function(index) {
return productHasItems(index);
}
$scope.cartItemHasVideos = function(index) {
return cartItemHasVideos(index);
}
$scope.cartItemHasLiterature = function (index) {
return cartItemHasLiterature(index);
}
$scope.getCartMailToBody = function () {
getCartMailToBody();
}
$scope.cartMailtoLink = getCartMailToBody();
$scope.logSentItems = function () {
logSentItems();
}
});
Thank you very much for your time. Let me know if you need more information or if I am being unclear.
I'm going to assume that app points to a declaration of that module that is defined at the root of your app e.g. in app.js:
app = angular.module('app', []);
And that you're including each dependency within your index.html e.g. after any angular scripts and app.js
<script src="yourDependency.js"></script>
In terms of the controller code itself, you don't need to assign to $scope a property that contains a function that calls the removeVideoFromCart service within your 'ModalInstanceCtrl' controller, because then you will still need to call that wrapper function again (which it currently looks like you are not doing).
You can just call the method within the controller rather than wrap it in a function e.g.
$scope.removeVideoFromCart = removeVideoFromCart(video, familyIndex, index);
or just call the service e.g. if you don't need to bind the data to the UI like sending form data that on success just redirects elsewhere (although in your case it looks like you do want to bind the data to the UI):
removeVideoFromCart(video, familyIndex, index);
It's not clear from your code where the parameters for each service originate from. Are they within the items object? e.g.
var video, familyIndex, index
vm.items = items;
video = items.video;
familyIndex = items.familyIndex;
index = items.index;
In terms of style, I prefer not assigning the module instances to a variable and instead use the setter syntax (following [John Papa's] (https://github.com/johnpapa/angular-styleguide#modules) styleguide, but also included in Todd Motto's), like so:
angular
.module('app')
.controller('ModalInstanceCtrl', ModalInstanceCtrl);
ModalInstanceCtrl.$inject['your', 'dependencies', 'go', 'here']
function ModalInstanceCtrl(/*dependencies here as parameters e.g.*/, removeVideoFromCart) {
var vm = this; // use in place of $scope and clarifies the context of the this keyword
vm.items = items;
video = items.video;
familyIndex = items.familyIndex;
index = items.index;
$scope.removeVideoFromCart = removeVideoFromCart(video, familyIndex, index);
$scope.removeLiteratureFromCart = removeLiteratureFromCart(literature, familyIndex, index);
//etc
});
NB: I would prefer a facade into all of those methods e.g. clearCartAndCloseModal('other', 'services') to hide all of the implementation details from the controller. This also makes it easier to create one controller per view that is in turn easier to test beacuse you have pushed all logic into the services. But I'm not clear from your code whether there is any relationship between each of the services.
#Claies #ritesh I was typing a long edit with responses to the questions when I happened upon my solution. I had multiple functions that opened modal windows using ModalInstanceController. For example, here are two:
$scope.open = function(size) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function() {
return $scope.selectedVideo3;
}
}
});
modalInstance.result.then(function(selectedItem) {
$scope.selected = selectedItem;
}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
$scope.openCart = function(size) {
var modalInstance = $modal.open({
templateUrl: 'myAttachmentModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function() {
return "";
},
removeVideoFromCart: function() {
return $scope.removeVideoFromCart;
},
removeLiteratureFromCart: function() {
return $scope.removeLiteratureFromCart;
},
productHasItems: function() {
return $scope.productHasItems;
},
cartItemHasVideos: function() {
return $scope.cartItemHasVideos;
},
cartItemHasLiterature: function() {
return $scope.cartItemHasLiterature;
},
getCartMailToBody: function() {
return $scope.getCartMailToBody
},
cartMailtoLink: function() {
return $scope.cartMailtoLink
},
logSentItems: function () {
return $scope.logSentItems;
}
}
});
modalInstance.result.then(function(selectedItem) {
$scope.selected = selectedItem;
}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
I only use most of the dependencies for ModalInstanceController in the openCart function, so I didn't add all of the dependency function declarations to my other open methods (You can see in the resolve for the $scope.open method above I only declare items and no functions).
I needed to declare all of these functions like I did in $scope.openCart and it fixed my problem.
Thank you for reaching out.
My case was UpperCase LowerCase problem in the injected service name.

How to get data from http request in angular ui bootstrap model

I am trying to get data from http request inside angular ui bootstrap modal here is my modal code
$scope.open = function (size, id) {
$scope.hallName=[];
var modalInstance = $modal.open({
templateUrl: 'video_gallery.html',
controller: HomeCtrl1,
size: size,
resolve:{
hallId:function(){
$http({
url:"../home/get_hall_name/"+id,
method: "POST"
}).success(function (data) {
$scope.hallName=data.hall_name;
alert($scope.hallName);
}).error(function(){
console.log("Something went wrong get_RegisteredHalls");
});
var hall=$scope.hallName;
return hall;
}
}
});
};
var HomeCtrl1 = function ($scope, $modalInstance, hallName) {
$scope.hallName = hallName;
$scope.selected = {};
$scope.ok = function () {};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
Here is what I am trying to get hall_name
<script type="text/ng-template" id="video_gallery.html">
<div class="modal-header">
<h4 class="modal-title" style="text-align:center;">Videos of {{hallName}} Hall</h4>
</div>
</script>
I am getting hall_name in alert but cant able to get that in view. please help me to save my day. Thanks in advance.
In order to wait for the http promise to resolve, you need to return it from your function:
hallId:function(){
return $http({
url:"../home/get_hall_name/"+id,
method: "POST"
}).success(function (data) {
}).error(function(){
console.log("Something went wrong get_RegisteredHalls");
});
}
Then in your controller you get this resolved promise:
var HomeCtrl1 = function ($scope, $modalInstance, hallId) {
$scope.hallName = hallId.data.hallName;
$scope.selected = {};
$scope.ok = function () {};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
Make sure you have the same name in both the resolve function and the controller (hallId in this case)
There's a couple of confusions.
First, between resolve and model $scope
from documentation,
scope - a scope instance to be used for the modal's content (actually the $modal service is going to create a child scope of a provided scope). Defaults to $rootScope
resolve - members that will be resolved and passed to the controller as locals; it is equivalent of the resolve property for AngularJS routes
Then, you have 2 options to "pass data" to your modal :
Using resolve. If I understand correctly, following code :
$scope.open = function (size, id) {
var modalInstance = $modal.open({
resolve:{
hallId: function() {
return "Walter white";
}
}
});
}
var HomeCtrl1 = function ($scope, $modalInstance, hallId) {
//hallId == "Walter white"
}
injects a hallId variable inside your controller. So inside resolve you provide the code to fill hallId and you get it in your controller, injected as hallId.
Using scope. For example
$scope.open = function (size, id) {
var modalScope = parent.$new();
modalScope.whatever = "Jessee Pinkman";
var modalInstance = $modal.open({
scope: modalScope
});
};
var HomeCtrl1 = function ($scope, $modalInstance) {
//$scope.whatever == "Jessee Pinkman"
}
Then, between synchronous and asynchronous
Inside resolve, you are making an asynchronous $http call, but return synchrounously the expected result. Therefore, this piece of code
var hall=$scope.hallName;
return hall;
is executed before this one
.success(function (data) {
$scope.hallName=data.hall_name;
alert($scope.hallName);
})
I am getting hall_name in alert but cant able to get that in view
Now you understand why.

Resources