Angular 1.5 and new Component Router - angularjs

I'm using angular 1.5 beta 2 and the new router from Angular 2 alpha 45.
I couldn't find examples of usage for the latest router with Angular 1.
I can find examples of the usage of the router for Angular 2, using #RouteConfig.
Can someone explain how I would configure an angular 1 controller? And, if possible, a full working example?

Update They have stopped working on this version of the Router and started a version 3 with different APIs. As of June 20, 2016 there was no recommended way for using the router v3 with Angular 1. I'm not sure if this has changed since. This question and answer below relates to Router v2 (aka ComponentRouter).
Obsolete API
A few sites indicate that a component in Angular 1 (for the purpose of the new router) is a controller registered as [name]Controller and a template picked up from component/[name]/[name].html. This is now obsolete.
New API
This discussion contains recent information, explaining how to get the latest Angular 1 new router version.
The component used in the configuration is mapped to a directive registered with the component name. See this sample.
angular.module('app.home', [])
.directive('home', function() {
return {
template: 'Hello {{ home.text }}',
controller: function HomeController() {
this.text = 'World';
},
controllerAs: 'home'
}
});
With Angular 1.5 there is a new syntax for registering components, see here. I've used it with this syntax:
angular.module('app.home', [])
.component('home', {
restrict: "EA",
template: 'Hello {{ home.text }}',
controller: function HomeController() {
this.text = 'World';
}
// to configure a child route
//,$routeConfig: [
// { aux: "/son", component: "son", as: "Left" },
// { aux: "/daughter", component: "daughter", as: "Left" }]
});

Although it is pretty new at this point you can also use a root component with the new angular router. This component could take additional components as children.
I followed Pete Bacon Darwin's example to get a version going.
https://github.com/petebacondarwin/ng1-component-router-demo
Notice in his version The main component has $router.config passed in the run block and identifies children with 3 dots.
.run(function($router) {
$router.config([
{ path: '/...', name: 'App', component: 'app', useAsDefault: true }
]);
I am using angular 1.5.0 to follow his github. I ran into issues playing with release some of the release candidates.

Related

AngularJS UI-Router won't display all Components (only some)

I've successfully replicated my issue with a fork of the "Hello Galaxy!" plunk embedded within the UI-Router tutorial page.
My plunk: https://plnkr.co/edit/2GqCtEJ4mhBIdJOFHy9c?p=preview
On the existing "Helo Galaxy!" plunk, I added the following module and route config:
// file: hello.js
// existing "Hello Galaxy!" hello module code above this ↑↑↑
// then my new module below...
angular.module('hello.product-management', ['ui.router']).config(function($stateProvider) {
// An array of state definitions
var states = [
{
name: 'product-management-template',
url: '/product-management-template',
// Using component: instead of template:
template: '<h1>Product Management</h1>'
},
{
name: 'product-management-component',
url: '/product-management-component',
// Using component: instead of template:
component: 'product-management'
},
]
// Loop over the state definitions and register them
states.forEach(function(state) {
$stateProvider.state(state);
});
});
The issue: You can click on the Product Management - Template tab to see the Product Management template, like so:
But you can't view the component template, using the Product Management - Component tab. It just shows an empty view:
I left the original "Hello Galaxy!" plunk's components and routes alone, and they still work fine:
In the state definition, use camelCase for the component name:
{
name: 'product-management-component',
url: '/product-management-component',
// Using component: instead of template:
̶c̶o̶m̶p̶o̶n̶e̶n̶t̶:̶ ̶'̶p̶r̶o̶d̶u̶c̶t̶-̶m̶a̶n̶a̶g̶e̶m̶e̶n̶t̶'̶
component: 'productManagement'
},
And define the component with camelCase:
̶a̶p̶p̶.̶c̶o̶m̶p̶o̶n̶e̶n̶t̶(̶'̶p̶r̶o̶d̶u̶c̶t̶-̶m̶a̶n̶a̶g̶e̶m̶e̶n̶t̶'̶,̶ ̶{̶
app.component('productManagement', {
template: '<h1>Product Management</h1>',
controller: function () {
console.log("product management component");
}
});
For more information, see AngularJS Developer Guide - Directive Normalization

UI-Router $stateParams Not Returning Values

Angular 1.6.9, UI-Router 1.0.15
The objective is the use the resolver to return the values for binding into Angular components. I have two third-party examples that work, one the tutorial Hello Galaxy example at the UI Router site and another a simple case in Codepen.
https://plnkr.co/edit/XdKQmifZ69pcYeBnQ945?p=preview
See the Pen Angular JS UI-Router State Params by David (#StretchKids) on CodePen.
However, no matter how I cut and paste, I haven't been able to get the resolver function in my Codepen Project to see the passed object. The object config is in the fred.js and ethel.js under components. The button passing the object is in the index.pug file (Codepen also makes the index.html available).
The program goes to the state and executes the resolver function. However both $stateParameters and $transition$.params() are empty. Ugh!
The snippet does not execute.
.module("MyApp")
.component("fred", {
templateUrl: "components/fred.html",
bindings: { name: "#" },
controller: function($stateParams){
var vm = this;
vm.activeId = $stateParams.id;
vm.resolveId = this.name;
}
})
.config(function($stateProvider) {
$stateProvider.state({
name: "fred",
url: "/fred",
component: "fred",
resolve: {
name: function($transition$, $stateParams) {
;
return $stateParams.id;
}
}
md-button(ng-repeat="name in ac.lvl1" ui-sref-active="active" ui-sref="{{name}}({id: 'bar'})") {{name}}
This is a link to the CodePen project: https://codepen.io/StretchKids/project/editor/AJPvQm#
HELP!!!
Thanks,
David
After quite a bit of searching and testing, I found the answer. First I broke the UI-Router Hello Galaxy example. Searching said passed parameters had to included in the URL.
That explained why the Hello Galaxy example passed the id of the person and then searched the people array of person objects rather than just passing the person object which it already had. Definitely the long way around the barn!
What was needed was the addition of a params object in the state definition to declare the $stateParams variables in advance.
{
name: "person",
url: "/{person.id}",
component: "person",
params:{data:null},
resolve: {
person: function($stateParams,$transition$) {
return $stateParams.data.person;
}
}
}
https://ui-router.github.io/guide/states#state-properties
https://ui-router.github.io/ng1/docs/1.0.14/interfaces/state.statedeclaration.html#params
http://benfoster.io/blog/ui-router-optional-parameters
This may be the best of the group: https://ui-router.github.io/guide/ng1/route-to-component

Using Ui-Router and adhering to good design patterns

Learning Angular. Working with 1.6.6.
Trying to use ui.router, running into an issue with injecting components.
I've been using the following as resources to structure my project:
AngularJS: Understanding design pattern
https://github.com/angular-app/angular-app
Both these resources suggest using module as a container for the code underneath them. For example from my own project:
angular.
module('randomTownGenerator.module', [
'randomTown.service',
'randomTown.controller'
]);
Each of those dependancies is defined in its own file. When I specify the above module as the component for the the route:
var randomTownGenerator = {
name: 'randomTownGenerator',
url: '/random-town',
component: 'randomTownGenerator.module'
}
I get:
Error: [$injector:unpr] Unknown provider: randomTownGenerator.moduleDirectiveProvider <- randomTownGenerator.moduleDirective
How can I pass the randomTownGenerator.module, which is just a wrapper around the service, template, and controller, to ui.router?
You have provided a module where it is expecting an angular component.
component: 'randomTownGenerator.module'
Here angular-ui-router is expecting a angular component to generate as the view for the state 'randomTownGenerator'. Please refer the angularjs documentation on how to create a component.
https://code.angularjs.org/1.6.6/docs/guide/component
You are trying to mixup the angularjs earlier version of injecting a module and new way of injecting module.
You should provide a component as a view with the later version so that will be loaded when it is required.
var States = {
"app": {
path: "",
routing: null,
definition: {
name: "app",
url: "",
onEnter: function () {
console.info("App state entered.");
},
params: {
//
},
resolve: {
//
},
views: {
"app#": {
component: "appComponent"
}
},
abstract: true
}
}
};
where component should be a component not a module. Here is a complete example of how to create states with ui-router and angularjs 1.6 version

What is the equivalent of angular-ui-router componentProvider in Angular 4 or angular-ui-router-ng2?

I have an AngularJS 1.6 app that loads a list of app modules fetched from the server. Every app has a different list of modules, so it would mean a lot of overhead code to create one unique route per module.
We are using ui-router, and it provides a really cool route config method called componentProvider which allows us to dynamically load a component pages on (in our case) the $routeParams.
Here is the working Angular 1.6 code:
//...
.state('applications.apps.modules', {
url: '/:moduleSlug',
data: {
addToSideMenu: false,
},
// create a dynamic component
componentProvider: ($stateParams: StateParams) => {
// This outputs "application-<name of module>"
return `application${capitalizeFirstLetter(snakeToCamel($stateParams.moduleSlug))}`;
},
resolve: {
application: (applications, $stateParams: StateParams) => {
return applications.filter(app => app.slug === $stateParams.appSlug)[0];
},
},
})
//...
This code will return a string application-<name of module>, and it allows us to load that module dynamically.
We're trying to find a way to do the same thing in that app but in Angular 4.
Any idea?

AngularJS, ui-router & Firebase app not working in Plunker

I just took an app I'm working on and converted it to a Plunk but Angular and/or ui-router is not populating the two views I have in index.html. On my local box the app loads fine but there I have the app modularize. So when I converted it to a Plunk I had to rewire the files together since I can't make modules in Plunker AFAIK. Also, when I load the Plunk in a separate window and open Dev Tools I get no errors so I'm at a loss right now.
Here is link to the Plunk code I made:
http://plnkr.co/edit/2f1RITT6ysZhB5i0UcUw?p=preview
And here is the link to the embedded view (more convenient if you want to use Dev Tools):
http://embed.plnkr.co/2f1RITT6ysZhB5i0UcUw/preview/posts
I should mention that the route has to end in /posts since that it the url of the state named posts. I have no state defined for the root / url. Also the following url failed:
http://embed.plnkr.co/2f1RITT6ysZhB5i0UcUw/posts
Thanks in advance.
I've made few changes. Here is a working plunker
Firstly I upgraded your version to UI-Router 0.2.13 (fixes some issues, simply always use the latest)
The /post is now default
//$urlRouterProvider.otherwise('/');
$urlRouterProvider.otherwise('/posts');
I changed your controller, to not use router params,
// wrong old
/*
app.controller('ProfileCtrl', function ($scope, $routeParams, Profile) {
var uid = $routeParams.userId;
$scope.profile = Profile.get(uid);
Profile.getPosts(uid).then(function(posts) {
$scope.posts = posts;
});
});
*/
// the way with UI-Router
app.controller('ProfileCtrl', function ($scope, $stateParams, Profile) {
var uid = $stateParams.userId;
$scope.profile = Profile.get(uid);
...
JUST to know what is post holding
Also, the passed userId into state contains values like: "simplelogin:82", to observe taht, I added overview of processed post, which is showing info like this:
{
"creator": "3lf",
"creatorUID": "simplelogin:82", // this is passed as userId, is it ok?
"title": "a",
"url": "http://a",
"$id": "-JazOHpnlqdNzxxJG-4r",
"$priority": null
}
Also, this is a fixed way how to call state posts.postview
<!-- wrong -->
<!-- <a ui-sref="posts({postId:post.$id})">comments</a> -->
<!-- correct -->
<a ui-sref="posts.postview({postId:post.$id})">comments</a>
And alos, if the postview should be injected into main area, this should be its defintion
var postView = {
name: 'posts.postview',
parent: posts,
url: '/:postId',
views: {
'navbar#': {
templateUrl: 'nav.tpl.html',
controller: 'NavCtrl'
},
//'#posts.postview': {
'#': {
templateUrl: 'postview.tpl.html',
controller: 'PostViewCtrl'
}
}
};
Check it all here
SUMMARY: Working navigation is among posts - users... the "comments" link is also working, but the target is just loaded ... with many other errors... out of scope here

Resources