Angularjs routing with variable appended - angularjs

Basically, this is a social sort of application that I am working on.
So, for this app to work, the '/home' state shows a list of users. The 'friends/X' (X being user id) shows the profile of that user.
So, here is my app with the ng controller in the element:
ng-click="profile({{friend.id}})"
This hooks up and sends a function call to my controller "HomeController" which is currently in "/home". My problem is, how do I open a new state and pass a variable, the friend.id in this case to the state?
Thank you :)
EDIT:
Basically I want to know how a function "profile" can capture the id, then call the new state and send it the variable id of friend.id
EDIT 2:
Basically, in the profile function which is in the "HomeController" it will accept a ID as a perameter, so for example "1", and it will use the value it received and send the application to a NEW state for example now the new state is going to be "ProfileController" and it will be "/home/profile" or something like that, and it will pass along the "1" into the url, like so: "/home/profile/1".

If you want to do this inside a function, you should use the $location service to change the URL. Then the route will update, and the profile controller can take over.
<a ng-click="profile(friend.id)">{{friend.name}}</a>
... And in the controller:
$scope.profile = function(id) {
$location.url('/home/profile/' + id);
};
However, unless you need to do something with the click before changing the route, you can probably just do it with an href:
<a ng-href="#/home/profile/{{friend.id}}">{{friend.name}}</a>
If you stick to this method and leave it to the routing mechanism to choose the right controller, then your user will be able to copy/bookmark/jump to that URL directly, and use the back/forward buttons in the browser.
Use the $routeProvider service to tell AngularJS which controller to use based on the URL. For example (this should go in your module's .config):
$routeProvider
.when('/home/profile/:friendId', {
templateUrl: 'profile.html',
controller: 'ProfileController'
})
...etc
Then you can use $routeParams in ProfileController to get the current friendId parameter.

Related

How to pass data to other controller in Angular js?

I have 2 controllers, I want to have next thing:
when I click on item in controllerOne it should highlight element with the same ID in controllerTwo.
I have highlighting method But how to send event with ID from controllerOne to controllerTwo ??
Keep the shared data in a service that's accessible from both controllers, see https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#defer-controller-logic-to-services
Use $route to pass variables in the URL:
/controller2route/:action/:id
for example:
/details/highlight/2
You can then use ifs and switches to call the appropriate function, for example highlight(2) for the above URL.
https://docs.angularjs.org/api/ngRoute/service/$route
You can you route parameter in routing.
In routing
app.config(function($routeProvider) {
$routeProvider
.when("/users/:userId", {
templateUrl : "main.htm",
controller:"controllerTwo "
})
})
and in controllerTwo use $routeParams to get the user id.
app.controller('controllerTwo',function($scope,$routeParams){
var userId = $routeParams.userId;
})
and the one better solution is to use services. Here is the link
https://thinkster.io/a-better-way-to-learn-angularjs/services

Angular UI Router Wrong Template And Controller

I have an odd issue where I use an ng-click to $state.go() to a state, and get the correct url but the wrong template and controller.
These are my states:
app.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("/messages");
$stateProvider.state('message', {
url: "/messages/:to/:fro/:messageID",
templateUrl: 'message.html',
controller: 'MessageCtrl'
}).state('compose', {
url: "/messages/compose/a/message",
templateUrl: 'compose.html',
controller: 'ComposeCtrl'
});
});
This is the function triggered by my ng-click and I am in fact getting the console log so I know the right one is firing.
$scope.composeMe = function(){
console.log("You want to compose a message!");
$state.go("compose");
};
When I fire that function I get the url to change to http://example.com/messages/compose/a/message but I get the templateUrl and the controller of the message state.
Why is that? The other state is fired from a similar (ng-click derived) function and works perfectly.
The URL you are trying to go to matches the one you are actually going to.
How would ui-router know that "compose" isn't the to: field you want, "a" isn't the fro: field you want, and "message" isn't the messageID you want?
Move the more specific state definition above the one with URL parameters.

Angular UI router dynamically inject URL to html

I am trying to build a simple app, which goes the following way:
I have 2 menu items in the navbar: home and contact.
The home should be a unique URL only once from the server, at initialisation, read from a QR code (i got this covered, that is no problem to me) and the contact should always be the same.
I got the contact done in the following way:
$stateProvider.state('contact', {
url: '/contact',
templateUrl: 'src/views/contact.html',
controller: 'contactController'
})
The problem is with the home, which should keep the unique URL received by the server. How should i write the state for that one?
.state('home', {
url: '/:uid',
templateUrl: 'src/views/home.html',
})
Also, the home should keep it's unique url generated by the server after refresh and while navigating from contact to home.
In the HTML i would have something like
<a ui-sref="home({uid: --some dynamic uid?--})">Home</a>
this is the part which also requires help.
Set the home state to
.state('home', {
url: /{uid},
templateUrl: 'src/views/home.html',
})
and you could grab the parameters by injecting $stateParams into the controller. $stateParams.uid would return the parameters and store that in local storage or cookies.
Check this link out
https://github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service
UPDATE:
for example, this is the sample controller that is attached to the home page
app.controller('homeCtrl', function($stateParams) {
var id = $stateParams.uid; //this is how you retrieve the uid
});
by going to your home page e.g. http://www.example.com/abcd12345, the above $stateParams.uid would return abcd12345
Now to set the url. simply use ui-sref instead of href on the <a> tag. ui-router will automatically generate href for you.
e.g.
<a ui-sref="home({uid:'abcd12345'})">Home</a>
You have to create a custom provider and inject it into the config.
eg:- .config($stateProvider, $urlRouterProvider,yourprovider) .
I am not sure about this. But please check this way too..

Angular Redirect when url has no parameters

When user lost password, an email is sent to his account with an URL. I want the page that controls a reset password only loads if the url has a parameter. Im using Angular.
For example:
if user goes to http://example.com/reset_password/A232Ddade
loads the reset_password/reset_password.html page normally
but
if user goes to http://example.com/reset_password/
redirect to http://example.com/index.html
Another thing to consider is that before rendering the page, I will use the parameter to find the user that will change the password.
To make this happens I have to use some initialize function, read the parameter and if it is present use it or if it is not present redirect to index page? like
//At the top of the controller
var init = function () {
//check if there is query in url
//and redirect if not
};
//and fire it after definition
init();
Or Can I use the ui-router module?
Thanks.
It's look like standard usage of $routeProvider
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/reset_password/:param', {templateUrl: 'pageToReset.html', controller: ResetLogicCtrl}).
when('/reset_password/', {templateUrl: 'index.html', controller: IndexCtrl}).
otherwise({redirectTo: '/'});
}]);
You can do that with Resolve, on your route. Take the param and get the user with it, if there is no user, or if param is falsy value, redirect to wherever you want. That way your controller gets the needed data or it redirects.

Am I using states correctly?

I have an angular app with a homepage that shows a list of things. Each thing has a type. In the nav, there are selectors corresponding to each thing type. Clicking one of these selectors causes the home controller to filter the things shown to those of the selected type. As such, I see the selectors as corresponding to states of the home page.
Now, I'd like to map each of these states to a url route: myapp.com/home loads the home page in default (unfilitered) state, myapp.com/home/foo opens the home page with the foo-type selector activated, and switching from there to myapp.com/home/bar switches to the bar-filtered state without reloading the page.
It's that last bit - triggering "state" changes without reloading the page, that's been particularly tricky to figure out. There are numerous SO/forum questions on this topic but none have quite hit the spot, so I'm wondering if I'm thinking about this in the wrong way: Should I be thinking of these "states" as states at all? Is there a simpler approach?
Also, I'm open to using either ngRoute or ui.router - is there anything about one or the other that might make it simpler to implement this?
Using ui-router, you can approach it like this:
$stateProvider
.state('home', {
url: "/home",
controller: "HomeController",
templateUrl: "home.html"
// .. other options if required
})
.state('home.filtered', {
url: "/{filter}",
controller: "HomeController",
templateUrl: "home.html"
// .. other options if required
})
This creates a filtered state as a child of the home state and means that you can think of the URL to the filtered state as /home/{filter}. Where filter is a state parameter that can then be accessed using $stateParams.
Since you don't want to switch views, you inject $stateParams into your controller, watch $stateParams.filter, and react to it how you wish.
$scope.$watch(function () { return $stateParams.filter }, function (newVal, oldVal) {
// handle it
});

Resources