nested ui-router $location binding - angularjs

I have some problem with binding when i use ui-router. I am trying to make the app modular and keep it clean and simple.
I have the following app.js
// main routing - index.html
var app = angular.module('mainApp', ['ui.router']);
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('index', {
url: '/',
templateUrl: 'pages/main.html'
})
.state('cars', {
url: '/cars',
templateUrl: 'pages/Cars_model/main.html'
})
.state('cars.audi', {
url: '/audi',
templateUrl: 'pages/Cars_model/audi.html'
})
.state('cars.ford', {
url: '/ford',
templateUrl: 'pages/Cars_model/ford.html'
})
});
app.controller('indexController', function($scope, $location) {
$scope.isIndexPage = function() {
return $location.path() === '/';
}
});
app.controller('carsCtrl', function($scope, $location) {
if($location.path() === '/cars/audi')
{
$scope.pageHeader = "AUDI";
$scope.curentMenu = "Best Cars";
$scope.title = "Audi Specs";
}
if($location.path() === '/cars/ford')
{
$scope.pageHeader = "FORD";
$scope.curentMenu = "Best Cars";
$scope.title = "Ford Specs";
}
});
and the file where i want to use binding
<div class="container" ng-controller="carsCtrl">
<div class="page-header">
<h1>{{pageHeader}}</h1>
</div>
<!-- The first row -->
<div class="row">
<div class="col-lg-12 col-md-12 col-sd-12">
<ol class="breadcrumb">
<li>Home</li>
<li>{{curentMenu}}</li>
<li class="active">{{pageHeader}}</li>
</ol>
</div>
</div>
</div>
The problem is when i load the page the binding work only once, for the second i have to refresh the page.
I am not sure if i used the corect logic
if($location.path() === '/cars/ford')

I think i found the solution
Using
ui-sref-opts="{reload: true}"
in the menu solve the problem
<a ui-sref="cars.audi" ui-sref-opts="{reload: true}">Audi</a>
Plunker

Related

are these ui-sref states ie11 friendly

When trying to navigate with IE11, the links do not work with a state such as url: '/main-category/:id' but the "parent" state url: '/:main-category/' works fine. These are not true nested or parent-child since they don't actually share any common views/html template, except for navigation.
I found this meta tag suggestion and this IE events suggestion, but neither seem to be providing a solution for why my navigation bar AND links from another state do not function.
Here is a live site without minify, to test compare IE11 & all other browsers.
So, are these routes correctly setup?
router.js
angular.module('app_litsco')
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', { //this state works
url: '/',
templateUrl: 'html/home.html',
controller: 'controller_home',
})
.state('product_streamline', { //this state DOES NOT work
url: '/streamline_metal_panels/:id',
templateUrl: 'html/template_product.html',
controller: 'controller_prods',
})
.state('streamline_panels', { //this state works
url: '/:cat',
templateUrl: 'html/template_productlist.html',
controller: 'controller_productlist',
})
$locationProvider.html5Mode(true);
}]);
index.html
example NavBar section
<li class="link">
<!-- Main Category link -->
<a data-activates="streamline-panel-dropdown" class="blue-text text-darken-4 product-link" ui-sref="streamline_panels({ cat: 'streamline_metal_panels' })">STREAMLINE METAL PANELS</a>
<div id="streamline-panel-dropdown" class="dropdown-content dropdown-full full">
<div class="container dropdown-container flex-row-around-center">
<div class="col sm12 m3 text-center dropdown-item">
<!-- Sub-Category links -->
<a ui-sref="product_streamline({ id: 'classic_cr' })" class="product-link">Classic CR</a>
</div>
<div class="col sm12 m3 text-center dropdown-item">
<a ui-sref="product_streamline({ id: 'omniwall_md' })" class="product-link">Omniwall MD</a>
</div>
<div class="col sm12 m3 text-center dropdown-item">
<a ui-sref="product_streamline({ id: 'omniwall_cl' })" class="product-link">Omniwall CL</a>
</div>
</div>
</div>
</li>
Your product_streamline state uses Array.find() in a resolve, which IE doesn't support.
.state('product_streamline', {
url: '/streamline_metal_panels/:id',
templateUrl: 'html/template_product.html',
controller: 'controller_prods',
resolve: {
product: ['factory_litsco', '$stateParams', function (factory_litsco, $stateParams) {
var productIdObj = factory_litsco.find(function (obj) {
if (obj.id === $stateParams.id) {
return obj;
}
});
return productIdObj;
}],
$title: ['product', function (product) {
return product.productName;
}]
}
})
To detect these sort of errors, add a handler for $stateChangeError such as:
angular.element(document.getElementsByTagName('body')[0]).scope().$on('$stateChangeError', function() { console.log("Error", arguments) } )

ion-view not loading content

I'm using angular UI Router in Ionic to build an application but my one page news.html is not loading the content.It shows the view-title but not the stuffs inside ion-content , the page is blank.
this code is inside of a template news.html
<ion-view view-title="news">
<ion-content>
<div class="list card" ng-repeat="item in articles">
<div class="item item-thumbnail-left item-text-wrap">
<h2 class="post-title">{{item.name}}</h2>
<p class="post-author">{{item.description}}</p>
</div>
</div>
</ion-content>
</ion-view>
in app.js i have added the following ui route code
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('index', {
url: '/',
templateUrl: 'templates/home.html',
controller: 'mainCtrl'
})
.state('news', {
url: '/news',
templateUrl: 'templates/news.html',
controller: 'newsCtrl'
});
$urlRouterProvider.otherwise('/');
})
and my newsCtrl is
.controller('newsCtrl',function($scope, $http){
$http.get('https://newsapi.org/v1/articles?source=the-next-web&sortBy=latest&apiKey=4ff16a30e00640cab0a2a9731ccc9510').success(function(data){
$scope.articles = data.sources;
console.log('news control');
});
Same code works
carService.controller('newsCtrl', ['$scope', '$http', function($scope, $http) {
$http.get('https://newsapi.org/v1/sources?language=en').success(function(data) {
$scope.articles = data.sources;
console.log(data);
console.log('news control');
});
}]);
DEMO

Checkout Step Navigation

i have no idea how to solve this Problem.
I have 4 Checkout Steps. Each Step has an Form to fullfill.
If Form is valid, the next Step in Navigation should be activated.
This is the Routing Script
"use strict";
var router = angular.module("router", ["ui.router"]);
router.config(["$stateProvider", "$urlRouterProvider", "$locationProvider", "$httpProvider",
function($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: true,
rewriteLinks: true
});
$stateProvider
.state("step1", {
url: "/step1",
controller: "Step1Controller",
templateUrl: "app/views/step1-partial.html"
})
.state("step2", {
url: "/step2",
controller: "Step2Controller",
templateUrl: "app/views/step2-partial.html"
})
.state("step3", {
url: "/step3",
controller: "Step3Controller",
templateUrl: "app/views/step3-partial.html"
})
.state("step4", {
url: "/step4",
controller: "Step4Controller",
templateUrl: "app/views/step4-partial.html"
});
$urlRouterProvider.otherwise("/step1");
}
]);
router.run(function($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
});
and this is one of the Partials View
<section class="steps">
<ul class="clear-list">
<li class="active">Step1</li>
<li>Step2</i></li>
<li>Step3</li>
<li>Step4</li>
</ul>
</section>
<form name="registerForm" ng-cloak>
formfields...
</form>
<div class="step-footer">
Next >
</div>
can somebody help me out
In processData() function (which i am hoping you will we having in all three controllers) after successful processing of data you can do $location.path('/step2');
and so on for all the steps.
For activating the current section in which currently you are, you can have some common variable in all three controller and set the value of that variable like ($scope.currentStep = step1) respectively.
Example.
<section class="steps">
<ul class="clear-list">
<li ng-class="{active : currentStep=='step1'}">Step1</li>
<li ng-class="{active : currentStep=='step2'}">Step2</i></li>
<li ng-class="{active : currentStep=='step3'}">Step3</li>
<li ng-class="{active : currentStep=='step4'}">Step4</li>
</ul>
</section>
use ui-sref-active="active" instead of class

How do i organize my angularjs page?

I'm trying to create my first angularjs page. A small wishlist to my family.
My simplified html:
<body ng-controller="memberController">
<nav>
<div class="container">
<ul class="nav navbar-nav">
<li ng-repeat="member in members" ng-class="{'active': isActive(member)}">
<a ui-sref="member({memberId:member.pk})" ng-bind="member.name"></a>
</li>
</ul>
</div>
</nav>
<div ui-view></div>
My wish-list.html (simplified)
<ol class="breadcrumb">
<li><a ui-sref="home">Hjem</a></li>
<li class="active">{{member.name}}</li>
</ol>
And here is my app.js
'use strict';
var wishApp = angular.module('wishApp', [
'ui.router',
'memberController',
'memberService',
]);
wishApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('home', {
url: "/",
templateUrl: static_url('partials/index.html'),
})
.state('member', {
url: "/member/:memberId",
templateUrl: static_url('partials/wish-list.html'),
controller: 'WishFilterCtrl',
})
});
controllers.js
'use strict';
var memberController = angular.module('memberController', []);
memberController.controller('memberController', ['$scope', '$stateParams', 'Member', function($scope, $stateParams, Member) {
$scope.members = Member.query();
$scope.isActive = function(member){
if (member.pk == $stateParams.memberId)
$scope.member = member;
return member.pk == $stateParams.memberId;
};
}]);
services.js
var memberService = angular.module('memberService', ['ngResource']);
memberService.factory('Member', ['$resource', function($resource){
return $resource('/api/members/:memberId/', {memberId: '#pk'}, {
query: {method:'GET', isArray:true},
});
}]);
So my simple question is. Is this the right way to show member.name in breadcrumb or are there a more correct way to show this info inside the wishlist?
The member id is used to show wishes connected to a member. So should the call also return the member.name?
I hope this make sense or else please ask for further details.
Started working in angular 2, so i close this question.

AngularJS $location.path() changed after upgrading to 1.1.15

I have a NavigationController that has a selectedItem for the current selected item in a navigation list. It uses $location.path() to try and set it to a default value. It's in hashbang mode. Here is a simplified version:
App.controller("NavigationController", ['$scope', '$location', function($scope, $location) {
$scope.currentSelection = $location.path() || "/dashboard";
$scope.select = function( name ) {
$scope.currentSelection = name;
}
}]);
And the html:
<body ng-app="App">
<div class="container-fluid absoluteFill">
<div class="row-fluid fill" ng-controller="NavigationController">
<div class="span2 nav-bubble fill">
<ul class="nav nav-list">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
</div>
<div ng-view></div>
</div>
</div>
</body>
And the config:
angular.module("App", ["ngResource"])
.config(function($routeProvider) {
$routeProvider.
when( '/', { redirectTo: '/dashboard' }).
when( '/dashboard', {
controller: 'DashboardController',
templateUrl: '/gpa/app/views/dashboard.html'
}).
otherwise({redirectTo: '/'});
})
The problem is that when I navigate to /home/index (without a hash bang) $location.path() returns "/index" where it used to return null prior to 1.1.15. However, if I go to "/home/index#/dashboard it returns "/dashboard" as expected. I tried redirecting when someone goes to "/" to "/dashboard", but NavigationController is called prior to being redirected so it continues to get "/index".
So how can I at least tell when the hashbang is not included? $location.hash() always seems to return "". I don't want to hard code "/index" in my code to know when nothing is on the URL.
I think you want to use the $route service and hook into the $routeChangeSuccess event.
App.controller("NavigationController", function($scope, $location) {
$scope.$on("$routeChangeSuccess", function (scope, next, current) {
$scope.currentSelection = $location.path() || "/dashboard";
});
$scope.select = function( name ) {
$scope.currentSelection = name;
}
});

Resources