Angular JS RouteProvider does not call - angularjs

I'm working on an e-commerce like webapp to learn Angular. I have a menu on my home page (common and visible on all pages), which provides available products for e.g. Books, Clothes etc.
On my menu I have list items as follows:
<li>Computers</li>
<li>Academics & Professional</li>
searchProduct function in my first controller sets the selected product in scope and sets the location.path.
$scope.searchProduct =function(productTBSearched){
$scope.TBFProduct=productTBSearched;
$location.path("/SearchProducts");
}
I also have route provider in my first controller which refers to another html and 2nd controller.
$routeProvider.when("/SearchProducts", {
templateUrl: "./views/HomeSearchProducts.html" ,
controller: "productSearchCtrl"
});
In my second controller, I call a REST WS to search DB and build my Response JSON. The issue is when I click on the first item on menu at home page, I get search results and I can see my URL gets changed to ".......Index2.html#/SearchProducts"
Now at this page when I try to choose another menu item, Routeprovider does not call the "ProductSearchCtrl" again and no Ajax call is executed for newly selected item. Could anyone help on this?

I think you are trying to reload the route. You can update your code to something like below in order to reload the route.
$scope.searchProduct =function(productTBSearched){
$scope.TBFProduct=productTBSearched;
if($location.path() === "/SearchProducts") {
$route.reload();
} else {
$location.path("/SearchProducts");
}
}

Related

making a ui-sref functionality in a .js

Setting:
I have an angular app.
What I have:
I have this: ui-sref="providerDetail({id:provider.id})" functioning.
It is a functioning link to a page giving details on a given provider.
What I want:
I have a button that submits a form and makes a new provider. This works. But I also want this button to forward the user to that new provider's detail page.
I have a function running that prints the id of the new provider to the console when it is made, I just can't figure out how to forward the user to the appropirate location.
Note:
I can add this to the function:
window.location = "/dashboard.html#!/providerDetail/" +id;
And it will take me to the new page, but I get this impression that this is a bad route to take.
Don't manually change the URL in AngularJS application, do it in Angular way so that you don't need to worry about manually kick of digest cycle. From function you could call $state.go method to navigate between states.
function myFunction(id) {
$state.go('providerDetail', { id: id})
}
Note: Please make sure you inject $state inside you controller.

Pass service result to other controller

I am calling getLanguageSpecificData(LangCode) service from home controller and saving the data into localStorage. On Home page there are Language links, if user click on English then it will redirect to a second template. But the problem is that still home controller getLanguageSpecificData(LangCode) service is not completed its execution.So in second Controller when I am trying to get result from localStorage it is incorrect(not updated).
So can you please tell which is better approach in this situation ?
HomeController code :
app.controller('homeController',function($scope,$localStorage,$appService){
$scope.loadlanguagefile = function(langcode){
$troubleshootingService.getLanguageSpecificData(LangCode).then(function(responce){
$localStorage.data = responce.data;
});
}
});
'loadlanguagefile' function is called when user click on Enlgish link and app is redirect to second template. here is secondController code :
app.controller('secondController',function($scope,$localStorage){
$scope.data = $localStorage.data;
});
As per my suggestion, you should use callback function to do your need full, when the function is called make the English click disable , and if your result is successful the make that enable. It will be something like this:
getLanguageSpecificData(LangCode,callback:(dataToReturn:any)=>void):any{
//logic here to get data to return
callback(dataToReturn);
}
For calling this method -
1- before calling the method make English click disable.
2- then call the method-
getLanguageSpecificData(imputLangCode,(result)=>{
//logic for data modification
//logic to enable English click
});
3- Enable the English click inside the call of the method.

Angular JS Scrolling to an element in another page

I am building a SPA using Angular 1.4 and Grails. In my home page I have 3 sections namely section1, section2 and section3 with the same ID. I have a dropdown menu on the top and I have used the scroll-to plugin to scroll to the respective sections on click.
<li ><a href scroll-to="section1">History</a></li>
My Problem is that when I move to another route, the dropdown menu will still be at the top and I am not sure how to get this to scroll to that element in the home route from another route. This is what I have tried.
<li >Economic Weight</li>
And in the route config I did this
when('/home/:section', {
templateUrl: '/euribron/js/app/templates/home.html',
controller: 'HomeController'
}).
and in controller I did this
if($routeParams.section) {
var element = document.getElementById($routeParams.section);
smoothScroll(element);
}
But this does not work when I am on the same route and it does not seem elegant. Is there an easier way to achieve this in an efficient way.
Instead of scroll-to plugin, you can use $anchorScroll service to manage autoscrolling. Please see this post's answer How to handle anchor hash linking in AngularJS. Basically, you need to set $location.hash() to the section's id that you can get from $routeParams and call $anchorScroll() function to handle the rest. Use different id for the sections.

AngularJS- Route to a page with an item selected

I have a page as shown in this plnkr example.
http://plnkr.co/edit/NKVVn4ga6lYOBWEblt0o?p=preview
When I click on a hyperlink(added on bottom of page) with href="#/test", I want it to open this page but with the one of the items in the list selected.
(The reason for trying to acheive this is I will have a url with this route in a different app and when clicking on the link I want this page open with the item selected.)
This is what my routeProvider code looks like
myItemsApp.config(['$routeProvider', function($routeProvider){
$routeProvider.
when('/test',{
templateUrl:'index.html',
}).
otherwise({
redirectTo:'/',
})
}]);
Can I do anything in here to set the third item (for example) in the list selected?
What I have done so far is I have tried doing a resolve in the routeProvider and some logic in the controller to set the third item in the list to be selected and has failed miserably.
Any help would be greatly appreciated.
this is actually very simple, if you already have your route just use $routeParams
to get the handle on the selected item id and then use that id to traverse your list and set the right element as active, as for your route, i don't recall ngRoute cause i haven't use it in a while, but you can just create other route, same controller, same template just make the url look like /test/:item_id

Updating URL in Angular JS without re-rendering view

I'm building a dashboard system in AngularJS and I'm running into an issue with setting the url via $location.path
In our dashboard, we have a bunch of widgets. Each shows a larger maximized view when you click on it. We are trying to setup deep linking to allow users to link to a dashboard with a widget maximized.
Currently, we have 2 routes that look like /dashboard/:dashboardId and /dashboard/:dashboardId/:maximizedWidgetId
When a user maximizes a widget, we update the url using $location.path, but this is causing the view to re-render. Since we have all of the data, we don't want to reload the whole view, we just want to update the URL. Is there a way to set the url without causing the view to re-render?
HTML5Mode is set to true.
In fact, a view will be rendered everytime you change a url. Thats how $routeProvider works in Angular but you can pass maximizeWidgetId as a querystring which does not re-render a view.
App.config(function($routeProvider) {
$routeProvider.when('/dashboard/:dashboardId', {reloadOnSearch: false});
});
When you click a widget to maximize:
Maximum This Widget
or
$location.search('maximizeWidgetId', 1);
The URL in addressbar would change to http://app.com/dashboard/1?maximizeWidgetId=1
You can even watch when search changes in the URL (from one widget to another)
$scope.$on('$routeUpdate', function(scope, next, current) {
// Minimize the current widget and maximize the new one
});
You can set the reloadOnSearch property of $routeProvider to false.
Possible duplicate question : Can you change a path without reloading the controller in AngularJS?
Regards
For those who need change full path() without controllers reload
Here is plugin: https://github.com/anglibs/angular-location-update
Usage:
$location.update_path('/notes/1');
I realize this is an old question, but since it took me a good day and a half to find the answer, so here goes.
You do not need to convert your path into query strings if you use angular-ui-router.
Currently, due to what may be considered as a bug, setting reloadOnSearch: false on a state will result in being able to change the route without reloading the view. The GitHub user lmessinger was even kind enough to provide a demo of it. You can find the link from his comment linked above.
Basically all you need to do is:
Use ui-router instead of ngRoute
In your states, declare the ones you wish with reloadOnSearch: false
In my app, I have an category listing view, from which you can get to another category using a state like this:
$stateProvider.state('articles.list', {
url: '{categorySlug}',
templateUrl: 'partials/article-list.html',
controller: 'ArticleListCtrl',
reloadOnSearch: false
});
That's it. Hope this helps!
We're using Angular UI Router instead of built-in routes for a similar scenario. It doesn't seem to re-instantiate the controller and re-render the entire view.
How I've implemented it:
(my solution mostly for cases when you need to change whole route, not sub-parts)
I have page with menu (menuPage) and data should not be cleaned on navigation (there is a lot of inputs on each page and user will be very very unhappy if data will disappear accidentally).
turn off $routeProvider
in mainPage controller add two divs with custom directive attribute - each directive contains only 'templateUrl' and 'scope: true'
<div ng-show="tab=='tab_name'" data-tab_name-page></div>
mainPage controller contains lines to simulate routing:
if (!$scope.tab && $location.path()) {
$scope.tab = $location.path().substr(1);
}
$scope.setTab = function(tab) {
$scope.tab = tab;
$location.path('/'+tab);
};
That's all. Little bit ugly to have separate directive for each page, but usage of dynamic templateUrl (as function) in directive provokes re-rendering of page (and loosing data of inputs).
If I understood your question right, you want to,
Maximize the widget when the user is on /dashboard/:dashboardId and he maximizes the widget.
You want the user to have the ability to come back to /dashboard/:dashboardId/:maximizedWidgetId and still see the widget maximized.
You can configure only the first route in the routerConfig and use RouteParams to identify if the maximized widget is passed in the params in the controller of this configured route and maximize the one passed as the param. If the user is maximizing it the first time, share the url to this maximized view with the maximizedWidgetId on the UI.
As long as you use $location(which is just a wrapper over native location object) to update the path it will refresh the view.
I have an idea to use
window.history.replaceState('Object', 'Title', '/new-url');
If you do this and a digest cycle happens it will completely mangle things up. However if you set it back to the correct url that angular expects it's ok. So in theory you could store the correct url that angular expects and reset it just before you know a digest fires.
I've not tested this though.
Below code will let you change url without redirection such as: http://localhost/#/691?foo?bar?blabla
for(var i=0;i<=1000;i++) $routeProvider.when('/'+i, {templateUrl: "tabPages/"+i+".html",reloadOnSearch: false});
But when you change to http://localhost/#/692, you will be redirected.

Resources