access resolve in component controller in angularjs 1.5 - javascript

I am trying to bind to an angularjs 1.5 component a resolve value without success, In the state definition, I have replaced the common value of template properties with a value of the name of my new component. like this:
.state('eventslogs.create', {
url: '/create',
template: '<addevent data="$resolve.addevent"></addevent>.',
resolve: {
addevent: newEventslog
},
data: {
roles: ['admin'],
pageTitle: 'Eventslogs Create'
}
})
NewEventslog is a function that injects one of my services
newEventslog.$inject = ['EventslogsService'];
function newEventslog(EventslogsService) {
return new EventslogsService();
}
In my controller I have tried several ways but nothing works
angular.module('eventslogs')
.component('addevent', {
templateUrl: 'addevent.client.component.view.html',
bindings: {
data: '<'
},
controller: function($scope, $element) {
var vm = this;
vm.eventslog = vm.data;
}
But vm.eventslog always results in an undefined value, what's wrong with my aproach?, If I use "#" instead "<" in bindings, vm.addevent results in a string with value "$resource.addevent" and not like an instance of newEventslog function.
I am using ui-route version 0.2.18

not sure but try this inside the component
this.$onInit = () => {
vm.eventslog = vm.data;
}

Related

how to pass object in child component to the parents in angularJS

i'm looking to make a mulit step from in angularJS 1.5x and here is my file format
-events
--events.component.js
--events.controller.js
-form.component.js
-form.controller.js
in my form.component.js i am using UI router to route to the different parts of the form..
var createForm = {
templateUrl: 'app/components/event/form.html'
};
angular
.module('components.event')
.component('createEvent', createEvent)
.config(function($stateProvider) {
$stateProvider
.state('form', {
url: '/form',
component: 'createForm'
})
// nested states
.state('form.events', {
url: '/events',
component: 'createEvents'
})
});
in the parent controller(form.controller.js) i have an object $scope.formData:
function EventController($scope) {
$scope.formData = {};
}
angular
.module('components.event')
.controller('EventController', EventController);
I want to access $scope.formData from my events controller. I've tried using $scope.$parent.formData in events.controller.js which haven't worked for me yet
function EventController($scope) {
$scope.parentformData = $scope.$parent.formData;
}
angular
.module('components.event')
.controller('EventController', EventController);
any ideas on how i can do this?
Hope below code is helpful !
//No need to pass the .js file name.
//Just pass the name / element of your controller.
//eg:
// assuming this is your controller definition/declaration inside form.controller.js
function formController($scope) {
// code insde controller
}
// assuming this code is written inside events.controller.js
function EventController($scope) {
var formControllerScope = angular.element(formController).scope();
console.log(formControllerScope.formData);
}

Angular 1.5.x - Issue with nested components

First of all, I'm using components.
I have this "parent" component:
(function() {
'use strict';
angular
.module('parentModule', [])
.component('parent', {
templateUrl: 'parent.tpl.html',
controller: ParentCtrl,
transclude: true,
bindings: {
item: '='
}
});
function ParentCtrl() {
var vm = this;
vm.item = {
'id': 1,
'name': 'test'
};
}
})();
And I'm simply trying to share the object item with another component, like this:
(function() {
'use strict';
angular
.module('childModule', [])
.component('child', {
templateUrl: 'child.tpl.html',
controller: ChildCtrl,
require: {
parent: '^item'
}
});
function ChildCtrl() {
console.log(this.parent)
var vm = this;
}
})();
View (Parent):
Parent Component:
<h1 ng-bind='$ctrl.item.name'></h1>
<child></child>
View (Child):
Child component:
Here I want to print the test that is in the parent component
<h2 ng-bind='$ctrl.item.name'></h2>
Actually I'm getting the following error:
Expression 'undefined' in attribute 'item' used with directive
'parent' is non-assignable!
Here's the DEMO to illustrate better the situation
Can you explain to me how I can make it work?
You need to remove the bindings from yor parent component.
bindings binds to the component controller like scope binds to a directive's scope. You're not passing anything to <parent></parent> So you have to remove it.
Then your child component requires a parent component, not an item.
So
require: {
parent: '^parent'
}
Of course the child template should be modified to:
<h2 ng-bind='$ctrl.parent.item.name'></h2>
Finally, if from the child controller you want to log the item that is inside the parent, you will have to write:
function ChildCtrl($timeout) {
var vm = this;
$timeout(function() {
console.log(vm.parent.item);
});
}
I never need the timeout in my components, so there might be something obvious that I missed.
http://plnkr.co/edit/0DRlbedeXN1Z5ZL45Ysf?p=preview
EDIT:
Oh I forgot, you need to use the $onInit hook:
this.$onInit = function() {
console.log(vm.parent.item);
}
Your child should take the item as input via bindings.
(function() {
'use strict';
angular
.module('childModule', [])
.component('child', {
templateUrl: 'child.tpl.html',
controller: ChildCtrl,
bindings: {
item: '='
}
});
function ChildCtrl() {
console.log(this.parent)
var vm = this;
}
})();
So your parent template will look like
<h1 ng-bind='$ctrl.item.name'></h1>
<child item="$ctrl.item"></child>
The rest should work same.

AngularJS new router could not instantiate controller

I am trying to create a service to use throughout my Angular app that pulls in data from a .json file using $http. This is what the factory looks like:
var trooNewsServices = angular.module('trooNewsServices', []);
trooNewsServices.factory('Articles', ['$http',
function($http){
$http.get('resources/articles.json').success(function(data) {
return data;
});
}]);
I passed in the trooNewsServices dependency into my module declaration. Any controller that I try to pass in my new Articles service, I get a
"Could not instantiate controller HomeController"
error in the console. Not sure what I am missing/what is wrong with this code. Should I be using $resource instead of $http?
Here is how I am passing the 'trooNewsServices' into my main module:
var TrooNews = angular
.module('TrooNews', ['ngMaterial', 'ngNewRouter', 'trooNewsServices'])
.config(function($mdThemingProvider) {
$mdThemingProvider
.theme('default')
.primaryPalette('indigo')
.accentPalette('pink');
})
.config(function($locationProvider) {
$locationProvider.html5Mode({
enabled: false,
requireBase: false
});
});
Here is how I try to inject 'Articles' into one of my controllers:
TrooNews.controller('HomeController', ['Articles',
function(Articles) {
this.name = 'Troo News';
this.articles = Articles.query();
}]);
And here is how I set up routing in my 'AppController':
TrooNews.controller('AppController', function($router, $mdSidenav, $mdToast, $parse, $http) {
$router.config([{
path: '/',
component: 'home'
}, {
path: '/home',
component: 'home'
}, {
path: '/about',
component: 'about'
}, {
path: '/settings',
component: 'settings'
}, {
path: '/article/:id',
component: 'article'
}]);
this.toggleSidenav = function(menuId) {
$mdSidenav(menuId).toggle();
};
this.navigateTo = function(link) {
var parts = link.match(/^(.+?)(?:\((.*)\))?$/);
var url;
if (parts[2]) {
url = '.' + $router.generate(parts[1], $parse(parts[2])());
} else {
url = '.' + $router.generate(parts[1]);
}
$mdToast.show($mdToast.simple().content('Navigate To: ' + url).position('bottom right'));
$router.navigate(url);
this.toggleSidenav('left');
};
});
Inside your HomeController, you are executing this.articles = Articles.query();, but your Articles service doesn't define any query function.
Instead, your service is just immediately executing an HTTP GET request upon creation. Not sure why this would lead to your error, but it is a red flag.
Try changing your Articles service to the following:
trooNewsServices.factory('Articles', ['$http',
function Articles($http){
this.query = function() {
return $http.get('resources/articles.json')
.then(function(response) { return response.data; });
};
}]);
I was experiencing the same error message under different conditions. In my case, it was because I was referencing $scope in my dependencies (old habit that I'm trying to break). In my case, I wasn't using $scope and could easily remove the reference. That cleared up my error. Check your code for $scope references and see if that fixes it.
https://github.com/angular/router/issues/313
and
How can we watch expressions inside a controller in angular 1.4 using angular-new-router

Angular UI-Router - using "resolve" directly on template url

I am using UI-Router and want to change routing to be 'component based'. So Instead of defining a controller / template I want to use it like this:
.state('issue', {
url: '/someUrl/:number',
template: '<my-directive></my-directive>',
resolve: {
data: function(dataService) {
return dataService.getData().then(function(response) {
console.log(response.data);
return response.data;
});
}
}
})
Now, I know that with Angular's ngRoute I can use resolved data directly in the template, for example:
$routeProvider
.when('/', {
template: `<my-directive data="resolve.data"></my-directive>`,
resolve: {
data: function (dataService) {
return dataService.getData();
}
}
})
I couldn't do it using UI-Router (value was undefined).
Am I doing something wrong? Is it possible using ui-router?
The point with UI-Router is - result of resolve is available for a controller (related to template). So, we could do it like this:
.state('issue', {
url: '/someUrl/:number',
template: '<my-directive data="stateCtrlData"></my-directive>',
controller: function($scope, data) { $scope.stateCtrlData = data },
resolve: {
data: function(dataService) {
return dataService.getData().then(function(response) {
console.log(response.data);
return response.data;
});
}
}
})
The data are passed into controller and from its scope we pass it to directive.
If you mean injecting your data service, then you can do it like this (remember that the '' is telling to inject):
state('issue', {
url: '/someUrl/',
template: '<my-directive data="pep.data"></my-directive>',
controller: function( data) { this.data = data },
controllerAs: 'pep',
resolve:{
dataSvc : 'YourDataSvc',
campaign : function(dataSvc){
return dataSvc.getData();
}
}
Please remember a ui-view will be expected if you want to put additional views or child states.
Actually you can (tested only in ui-router v0.3.2)
There's an undocumented $resolve variable which is automatically injected in the controller.
Simply add 'controllerAs' property to the state as follows, and you can use $resolve in the template:
.state('issue', {
url: '/someUrl/:number',
template: '<my-directive data="vm.$resolve.data"></my-directive>',
controllerAs: 'vm',
resolve: {
data: function(dataService) {
return dataService.getData().then(function(response) {
console.log(response.data);
return response.data;
});
}
}
})

Angular ui-router: keep same ui-view for child

I need child state be able to use parent state's resolve functions. But I also need to keep same ui-view for both states. Here's a fiddle. And there's a code
$stateProvider
.state('parent', {
url: "/",
template: '<p>Hello {{parent.one}}</p><br>'
+ '<button ng-click="goToChild()">child</button><br>',
// this one below work but I don't need it
// template: '<p>Hello {{parent.one}}</p><br>'
// + '<button ng-click="goToChild()">child</button><br>'
// + '<div ui-view></div>',
resolve: {
test: function() {
return 1;
}
},
controller: function($scope, $state, test) {
$scope.parent = { one: test };
$scope.goToChild = function() {
$state.go('parent.child');
}
}
})
.state('parent.child', {
url: "/child",
template: '<p>Hello {{child.one}}</p>',
controller: function($scope, test) {
$scope.child = { one: test };
}
})
$urlRouterProvider.otherwise('/');
There is a working plunker.
The answer should be hidden/revealed in this two states definition:
parent with multi views
.state('parent', {
url: "/",
views: {
'#': {
template: '<div ui-view=""></div>',
controller: function($scope, $state, test) {
$scope.parent = { one: test };
$scope.goToChild = function() {
$state.go('parent.child');
}
}
},
'#parent': {
template: '<p>Parent says: hello <pre>{{parent | json}}</pre></p>'
+ '<br><button ng-click="goToChild()">child</button><br>',
}
},
resolve: {
test: function() { return 1; },
},
})
Child consuming parent resolve, and having its own
.state('parent.child', {
url: "^/child/:id",
template: '<p>Child says: hello <pre>{{child | json }}</pre></p>',
resolve: {
testChild: function() { return 2; },
},
controller: function($scope, test, testChild) {
$scope.child = {
one: test,
two : testChild,
parent: $scope.parent,
};
},
})
Check it here
And how it works? Well, it all is based on the:
Scope Inheritance by View Hierarchy Only
Keep in mind that scope properties only inherit down the state chain if the views of your states are nested. Inheritance of scope properties has nothing to do with the nesting of your states and everything to do with the nesting of your views (templates).
It is entirely possible that you have nested states whose templates populate ui-views at various non-nested locations within your site. In this scenario you cannot expect to access the scope variables of parent state views within the views of children states.
and also:
View Names - Relative vs. Absolute Names
Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname#statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.
For example, the previous example could also be written as:
.state('report',{
views: {
'filters#': { },
'tabledata#': { },
'graph#': { }
}
})
So, the above documentation cites are the core of the plunker. The parent uses multi views, one of them is unnamed - and will be used for inheritance. Parent also injects into that view its own "parent" view. The Resolve of a parent is in place...
Child now injects into anchor of its parent, which does have all the stuff needed. That means, that child does inherit scope and also resolve stuff. It shows its own resolve as well...

Categories

Resources