Passing data through open modal function Angular uibModal - javascript

I'm trying to figure out how to pass unit_number into the modal when it pops up. I'm pretty new with Angular and I'm a little confused with what resolve: and group: are doing and how I can include the unit_number in that return statement.
$scope.openTenantModal = function (unit_number) {
var modalInstance = $uibModal.open({
animation: true,
templateUrl: 'views/addtenantmodal.html',
controller: 'AddTenantModalCtrl',
size: 'large',
resolve: {
group: function () {
return $scope.group;
}
}
});
modalInstance.result.then(function () {
}, function () {
});
};

You are using ui-bootstrap
Bootstrap components written in pure AngularJS
To pass a variable to a modal's controller you need to use
resolve: {
A: function() {
return 'myVal'
}
}
And then you can access that variable 'A' from the modal`s controller by injecting it
controller: ['A', function(A) {
// now we can add the value to the scope and use it as we please...
$scope.myVal = A;
}]
Check out: https://angular-ui.github.io/bootstrap/#/modal
Resolve:
Members that will be resolved and passed to the controller as locals; it is equivalent of the resolve property in the router.
And group is just a member (it could be anything you choose)

Just add a property in resolve object unitNumber with a function returning unit_number value from it. So that you can get the unit_number value inside AddTenantModalCtrl by injecting unitNumber dependency in controller factory function.
resolve: {
group: function () {
return $scope.group;
},
unitNumber: function(){
return unit_number
}
}
Note: Don't directly do unitNumber: unit_number, because when you have that, angular DI system will try to search the dependency
with name unit_number(value) and It will try to evaluate it as
function. Resultant you will get $injector error in console.

Related

Load service data into angular component

I have a component which takes care of drawing two lists, but in the component there is no data so nothing is drawn.
myController
function loadAllData() {
Admin.getAllSettings()
.then(function (settings) {
$scope.settings = settings.data;
})
}
myComponent
{
bindings: {
selectedData: '=',
availableData: '<'
},
templateUrl: 'global/twoListSelector.directive.html',
controller: function () {
var me = this;
console.log(me);
}
}
myView
<two-side-selector selectedData="doctorProperties" availableData="settings"></two-side-selector>
In the console.log the output for me.settings is undefined. Shouldn't the digest cycle update the setting property so it gets to the component? The service is returning data correctly but it is not getting to the component
I am using angular 1.5.9
Try to use selected-data and available-data attributes at markup:
<two-side-selector selected-data="doctorProperties" available-data="settings"></two-side-selector>
AngularJS convert dash-separated attributes to camel-case by itself

Is there a way to send a promise from parent controller to child controller in angular?

Here is my parentController.js
angular
.module('myApp')
.controller('parentController', parentController);
parentController.$inject = [];
function parentController() {
init();
function init() {
return somePromise();
}
}
Here is my childController.js
angular
.module('myApp')
.controller('childController', childController);
childController.$inject = [];
function childController() {
init();
// need to wait for parentController init to finish
function init() {
}
}
I need the child controller to wait for parent controller initialization to be done.
I was thinking of using
$scope.broadcast();
But there always exist a possibility of race condition depending on how long somePromise takes.
Is there a way to pass in promise from parent controller to child controller?
Maybe is not what you are trying to achieve, But I believe that you can resolve this using the resolve property, like this:
.state('app.parent', {
url: 'parent/',
views: ...,
resolve: {
item: function() {
return somePromise();
}
},
controller: function(item) {
item
}
})
.state('app.parent.child', {
url: 'child',
views: ...,
resolve: {
itemChild: function(item) {
//Do something in case is nedeed
return item;
}
},
controller: function(itemChild) {
itemChild
}
})
Check out angular-ui-router like stated resolve might be able to help

How to pass dynamically generated data to a different state in Angular UI-Router

Question: how do I access a dynamically generated data in scope B, when I go from scope A and generate this data in scope A, using angular's ui-controller. Data is not available when the scope is initialized.
Note: I am fine with showing request data in the URL. I'm looking for the simplest way for new state to read data it needs and pass it to server and properly generate its contents.
When the page loads, it fetches data from server and populates scope "tests" with new data. This new data is shown on the page. I create links to scope "test" with this data. Links look like this:
<a ui-sref="test({id:test._id})">{{test.name}}</a>
On a rendered page it looks like this:
<a ui-sref="test({id:test._id})" class="ng-binding" href="#/test/57adc0e30a2ced3810983640">A test</a>
The href is correct and points to a database reference of an item. My goal is to have this reference as a variable in scope "test". My state provider:
$stateProvider
.state('tests', {
url: '/tests/',
templateUrl: 'test/index.html',
controller: 'Test.IndexController',
controllerAs: 'vm',
data: { activeTab: 'tests' }
})
.state('test', {
url: '/test/{id}',
templateUrl: 'test/item.html',
controller: 'Test.ItemController',
controllerAs: 'vm',
data: {
activeTab: 'tests',
testId: '{id}'
}
});
So far no matter what I tried I couldn't access "testId" in the "test" scope. It was either "undefined", created errors or returned "itemId: {id}".
My Item.Controller:
(function () {
'use strict';
function Controller(TestService) {
var vm = this;
vm.test = null;
function getTest(id) {
TestService.GetTestById(id).then(function(test) {
vm.test = test;
});
}
function initController() {
getTest(...);
}
initController();
}
angular
.module('app')
.controller('Test.ItemController', Controller);
})();
TestService provides http get methods for getting data from server.
(function () {
'use strict';
function Service($http, $q) {
var service = {};
function handleSuccess(res) {
return res.data;
}
function handleError(res) {
return $q.reject(res.data);
}
function GetTestById(_id) {
var config = {
params: {
testId: _id
}
};
return $http.get('/api/tests/:testId', config).then(handleSuccess, handleError);
}
service.GetTests = GetTests;
service.GetTestById = GetTestById;
return service;
}
angular
.module('app')
.factory('TestService', Service);
})();
I tried $scope - scope is not defined. I tried a number of other techniques, shown by other users with similar success - either "undefined" or error of some sort.
This is based on another person's code so there may be obvious mistakes, please let me know if you find any. If you need more code, let me know - I'll upload it to github (its a messy work in progress at the moment so I'm not sure what should be uploaded).

Use a modal ng-controller as a regular controller

I have a controller used by a modal view (with angularui). At some point I would like to use this controller with a custom view (not a modal one). So everything is fine except for the resolve variables (variables sent to the controller).
I call the modal like this:
var modalInstance = $modal.open({
templateUrl: 'myModal.html',
controller: 'modalCtrl',
size: 'lg',
resolve: {
variable: function(){
return myVar;
}
}
});
How can I send variables from javascript (or html)?
Here is how I bootstrap my custom view (custom.html):
angular.element($(document.body)[0].children[0]).attr('ng-controller','modalCtrl');
angular.bootstrap( document.body, [ 'myApp' ]);
One way to do this would be to define a service or a value with the same name of your resolve (variable in this case). Then Angular will find the dependency for you and inject it.
You may not want to always have this service/value defined. So you might define this service/value in a module, and then conditionally load that module when you bootstrap the app:
if (someCondition) {
angular.module('use.me.conditionally', []).value('variables', 123);
angular.element($(document.body)[0].children[0]).attr('ng-controller','modalCtrl');
angular.bootstrap(document.body, ['myApp', 'use.me.conditionally']);
} else {
angular.bootstrap(document.body, ['myApp']);
}
EDIT:
You can use the value() or service() functions to declare injectable objects that have many properties:
var foo = { property1: 'abc', property2: 456 };
angular.module('use.me.conditionally',[])
.value('variablesAsAValue', foo)
.service('variablesAsAService', function() { return foo; });
Note that you don't need both value() and service(), I'm just showing both approaches. value() is typically used for constant type of variables, and services are typically object/classes.

Angular How to pass scope to view from service?

i have global function in helper service.
this.displayModalWithInput = function ($scope, title, cotroller, functionCallback) {
$scope.modalProperties = {
modalTitle : title,
modalController : cotroller,
modalFunction : functionCallback
};
$('#myModal').modal();
};
In my template i have standard Bootsrap modal window. Problem is if i'm trying to access to scope using:
{{modalProperties.modalTitle}}
Nothing is displayed.
How can in solve it, if i want to use global available function and pass data from this global function into accessible scope?
Thanks for any advice.
first define $scope.modalProperties=[]; in your controller.
Then, when you call displayModalwithInput function from controller, there please pass $scope as one of arguments. e.g. displayModalwithInput($scope, ...)
if it doesn't work, i'd like to see your global service code.
Services (factories) are singletons and its not good practice (I would say you can't) to inject scope to service.
In your case to avoid code duplicate I would create directive instead (isolate scope) where in link function you can write all relevant logic.
This Demo might help you PLUNKER
Directive Example
.directive( 'confirmPopup', function () {
return {
restrict: 'A',
replace: true,
scope: { title: '#', content: '#', placement: '#', animation: '&', isOpen: '&', func: '&' },
templateUrl: 'confirmPopup.html',
link: function ($scope, element, attrs) {
$scope.confirm = function(){
$scope.$parent.deleteThing();
$scope.$parent.tt_isOpen = false;
}
$scope.cancel = function(){
$scope.$parent.tt_isOpen = false;
}
}
};
})

Categories