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

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.

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);

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

How can I passing Parameter angularjs factory $http and $stateParameters

App.factory('menuService', function ($http) {
var urlBase = 'Services/MenuService.asmx/GetAllMenu';
var factory = {};
factory.getAllMenus= function () {
return $http.get(urlBase);
};
return factory;
});
Controller:
App.controller("sampleController", function ($scope, menuService) {
$scope.List = [];
var menuData=function(data, status){
$scope.List = data;
console.log($scope.List);
}
menuService.getAllMenus().success(menuData);
});
/// Working perfect...
How can i use same service by other controller?
I've tried this one but wrong...
App.controller("viewDetailMenu", function ($scope, menuService, $stateParams) {
$scope.menu = menuService.getMenu($stateParams.id);
});
Here I share image how it look..
Please help me!...
You need to have all functions/methods defined if you want to use them. You getMenu function/method is not defined so it will generate an error. Please look at below code. You can add number of functions. You factory is share by all controllers so you can use it in any controller.
App.factory('menuService', function ($http) {
var urlBase = 'Services/MenuService.asmx/GetAllMenu';
var factory = {};
factory.getAllMenus= function () {
return $http.get(urlBase);
},
factory.getMenu=function(id){
return $http.get(urlBase +"/ID="+ id) // write it according to your API.
}
return factory;
});
And then,
App.controller("viewDetailMenu", function ($scope, menuService, $stateParams) {
$scope.menu = menuService.getMenu($stateParams.id).success(function(data,status){
}).error(function(data,status){
});
});

Can I use $compile in an Angular service directly on a templateUrl instead of on raw HTML or a raw angular.element?

Given the following service that is meant to create a "dialog" element (i.e. a modal):
app.service('dialog', ['$document', '$compile', '$rootScope',
function($document, $compile, $rootScope) {
var body = $document.find('body');
var scope = $rootScope.$new();
this.createDialog = function() {
var dialogElem = angular.element('<div ng-include="\'/dialog.html\'"></div>');
$compile(dialogElem)(scope);
body.append(dialogElem);
};
}
]);
which can be utilized in a controller like so:
$scope.someFunction = function() {
dialog.createDialog();
};
Is there a way that I can use $compile or anything else to not have HTML in my service? I'd really prefer to just invoke a directive, so that running createDialog() immediately injects a directive into my DOM and thus the directive is responsible for linking a new controller and template together. If I'm going about this the wrong way I'm totally open to constructive ideas.
Of course you can!, here you go:
app.factory('modalService', function ($document, $compile, $rootScope, $templateCache, $http) {
var body = $document.find('body'),
modals = [];
var service = {
show: function (template, data, modal) {
// The template's url
var url = 'template/modal/' + template + '.html';
// A new scope for the modal using the passed data
var scope = $rootScope.$new();
angular.extend(scope, data);
// Wrapping the template with some extra markup
modal = modal || angular.element('<div class="modal"/>');
// The modal api
var api = {
close: function () {
modal.remove();
scope.$destroy();
modals.splice(modals.indexOf(api), 1);
},
replace: function (template, data) {
return angular.extend(api, service.show(template, data, modal));
}
};
// Adding the modal to the body
body.append(modal);
// A close method
scope.close = api.close;
// Caching the template for future calls
$http.get(url, {cache: $templateCache})
.then(function (response) {
// Wrapping the template with some extra markup
modal.html('<div class="win">' + response.data + '</div>');
// The important part
$compile(modal)(scope);
});
modals.push(modal);
return api;
},
showOrReplaceLast: function (template, data) {
return service.show(template, data, modals.length > 0 ? modals[modals.length - 1] : null);
}
};
return service;
});
Some notes:
You need to insert the modal somewhere in the DOM, that's why the $document is injected.
Yes, you can take the modal markup out of here.
Remember to create new scopes for the dialog and to destroy them ($rootScope.$new).
This is a WIP, I hope it's clear enough.
You could try this as below, just to render your ng-include before opening the dialog
app.service('dialog', ['$http', '$compile', '$q', '$templateCache'
function($http, $compile, $q, $templateCache) {
this.compileInclude = function(scope, url) {
var deferred = $q.defer();
$http.get(url, {cache : $templateCache}).then(function(response){
deferred.resolve($compile(response.data)(scope));
});
return deferred.promise;
};
}
]);
From the controller write as below
dialog.compileInclude($scope, 'dialog.html').then(function(){
// open dialog here
});

Angular ui-router get asynchronous data with resolve

I want to display a form with data corresponding to the edited item. I use ui-router for routing. I defined a state:
myapp.config(function($stateProvider) {
$stateProvider.
.state('layout.propertyedit', {
url: "/properties/:propertyId",
views : {
"contentView#": {
templateUrl : 'partials/content2.html',
controller: 'PropertyController'
}
}
});
In PropertyController, I want to set $scope.property with data coming from the following call (Google Cloud Endpoints):
gapi.client.realestate.get(propertyId).execute(function(resp) {
console.log(resp);
});
I don't know if I can use resolve because the data are returned asynchronously. I tried
resolve: {
propertyData: function() {
return gapi.client.realestate.get(propertyId).execute(function(resp) {
console.log(resp);
});
}
}
First issue, the propertyId is undefined. How do you get the propertyId from the url: "/properties/:propertyId"?
Basically I want to set $scope.property in PropertyController to the resp object returned by the async call.
EDIT:
myapp.controller('PropertyController', function($scope, , $stateParams, $q) {
$scope.property = {};
$scope.create = function(property) {
}
$scope.update = function(property) {
}
function loadData() {
var deferred = $q.defer();
gapi.client.realestate.get({'id': '11'}).execute(function(resp) {
deferred.resolve(resp);
});
$scope.property = deferred.promise;
}
});
You need to read the docs for resolve. Resolve functions are injectable, and you can use $stateParams to get the correct value from your routes, like so:
resolve: {
propertyData: function($stateParams, $q) {
// The gapi.client.realestate object should really be wrapped in an
// injectable service for testability...
var deferred = $q.defer();
gapi.client.realestate.get($stateParams.propertyId).execute(function(r) {
deferred.resolve(r);
});
return deferred.promise;
}
}
Finally, the values for resolve functions are injectable in your controller once resolved:
myapp.controller('PropertyController', function($scope, propertyData) {
$scope.property = propertyData;
});
I think your controller function needs $stateParams parameter from which you can get your propertyId. Then you can use $q parameter and create promise to set $scope.property with something like this:
var deferred = $q.defer();
gapi.client.realestate.get(propertyId).execute(function(resp) {
deferred.resolve(resp);
});
$scope.property=deferred.promise;
Here is description of using promises for handling async calls.
Try this easy way to use resolve in proper way
State code:
.state('yourstate', {
url: '/demo/action/:id',
templateUrl: './view/demo.html',
resolve:{
actionData: function(actionData, $q, $stateParams, $http){
return actionData.actionDataJson($stateParams.id);
}
},
controller: "DemoController",
controllerAs : "DemoCtrl"
})
In the above code I am sending parameter data which I am sending in the url,For examples if i send like this /demo/action/5
this number 5 will go to actionData service that service retrieve some json data based on id.Finally that data will store into actionData You can use that in your controller directly by using that name
Following code return some JSON data based on id which iam passing at state level
(function retriveDemoJsonData(){
angular.module('yourModuleName').factory('actionData', function ($q, $http) {
var data={};
data.actionDataJson = function(id){
//The original business logic will apply based on URL Param ID
var defObj = $q.defer();
$http.get('demodata.json')
.then(function(res){
defObj.resolve(res.data[0]);
});
return defObj.promise;
}
return data;
});
})();
How about this:
function PropertyController($scope, $stateParams) {
gapi.client.realestate.get($stateParams.propertyId).execute(function(resp) {
$scope.property = resp;
});
}

Resources