im just starting to learn angular and ioninc to build an app.
I just started a new app with ionic included and made a list of items from a json file. This works perfect, but since im jump into routing i just see a blank page and i don't get my mistake.
this is my index.html:
<!DOCTYPE html>
<html >
<head>
<meta charset="utf-8">
<title>Spätifinder</title>
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<link rel="stylesheet" href="css/ionic.css">
<script src="angular.min.js"></script>
<script src="js/ionic.bundle.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="spaetifinder">
<ion-header-bar type="bar-positive"
animation="nav-title-slide-ios7"
back-button-type="button-icon"
back-button-icon="ion-ios7-arrow-back"></ion-header-bar>
<ion-nav-bar class="bar-energized nav-title-slide-ios7">
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</body>
</html>
this is ma app.js file:
var app = angular.module('spaetifinder', ['ionic']);
app.config(function ($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
.state('home', {
url: '/',
templateUrl: 'home.html'
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/home');
});
app.controller('StoreController', [ '$http', function($http) {
var store = this;
store.storeList = [ ];
$http.get('http://m.xn--sptifinder-r5a.de/apiv1/jsonp.php?action=list&lat=52.437595&long=12.987900&distance=100').success(function(data){
store.storeList = data;
});
this.loadImage = function(hasImage){
if(hasImage = 0) {
return "http://www.spätifinder.de/images/fotos/no-foto.jpg";
}
else {
return this.ID;
}
};
}]);
and this should be my template for home (home.html)
<!-- our list and list items -->
<ion-list>
<a href="#" class="item item-thumbnail-left" ng-repeat="spaeti in spaetis.storeList">
<img ng-if="spaeti.has_image == 0" ng-src="http://www.spätifinder.de/images/fotos/no-foto.jpg">
<img ng-if="spaeti.has_image == 1" ng-src="http://www.spätifinder.de/images/fotos/{{spaeti.ID}}_crop.jpg">
<h2>{{spaeti.Name}}</h2>
<p>{{spaeti.BusinessHours}}<br>{{spaeti.Street}}, {{spaeti.ZIP}} {{spaeti.City}}</p>
</a>
</ion-list>
Im just don't get it what is wrong with that, maybe you see an mistake there?
thanks in advance
luc
I think that your issue is in your routing configuration. You only define one state at the / URL. You then set your fallback to /home which doesn't exist. You probably want your home state to be located at /home.
EDIT: Scratch that i think i see your problem, you have a ; at the end of your state block, i had to remove mine to get it to work it took me along time last night to figure that our, hope it helps you.
Old answer:
Im not sure maybe this will help but here is mine, the only thing i see wrong with yours is what #Jon7 already pointed out.
.state('main', {
url: "/main",
templateUrl: "templates/main.html",
controller: 'MainController'
})
$urlRouterProvider.otherwise('/main');
I had some trouble understanding the routing too. I learned a lot from this Codepen example.
Codepen example routing
You need to add controller and perhaps a view as well...
so from this
.state('home', {
url: '/',
templateUrl: 'home.html'
});
to
.state('home', {
url: '/',
views: { //optional
'viewname':{
templateUrl: 'templates/home.html'
controller: 'StoreController'
}
}
});
Your mistake is the otherwise statement. It should be:
$urlRouterProvider.otherwise('/')
var app = angular.module('ionicApp', ['ionic'])
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/')
$stateProvider.state('home', {
url: '/',
template: '<p>Hello, world!</p>'
})
})
$stateProvider.state('home', {
url: '/',
templateUrl: 'home.html'
})
http://learn.ionicframework.com/formulas/navigation-and-routing-part-1/
Related
I want to build a hybrid mobile app with Ionic. Here is my first trial via plunker. As you can see, my plunker shows a blank page. I did inspect what's the problem, but still not found. My goal is to create a login page in first time my app starts, then users will be redirected into home-page.html. Since it's just example, I don't want any authentication code, I only need to have all those route/links work well.
Please take a look in my index.html, if I replace all those code within ...... with a normal HTML tags, it's displaying as normal.
Head section:
<script src="http://code.ionicframework.com/1.1.1/js/ionic.min.js"></script>
<script src="http://code.ionicframework.com/1.1.1/js/ionic.bundle.min.js"></script>
<link href="http://code.ionicframework.com/1.1.1/css/ionic.min.css" rel="stylesheet" />
<link href="style.css" rel="stylesheet"/>
<script src="app.js"></script>
Body section
<script id="templates/login.htm" type="text/ng-template">
<ion-view ng-controller="LoginCtrl">
<ion-content>
<h1>Login page</h1>
<button type="button" class="btn btn-default" ng-click="logIn()">Login Press</button>
</ion-content>
</ion-view>
</script>
<script id="templates/home-page.htm" type="text/ng-template">
<ion-view>
<ion-content>
<h1>Home Page</h1>
</ion-content>
</ion-view>
</script>
In my app.js, I defined two states like this:
var app = angular.module('ionicApp', ['ionic']);
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('login', {
url: "/login",
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
})
.state('home', {
url: "/home",
templateUrl: 'templates/home-page.html'
});
});
app.controller('LoginCtrl', function($scope, $state, $location) {
$scope.logIn = function() {
//$state.go('/home');
alert('Clicked');
};
});
Any solution will be appreciated. Thanks.
not sure why but it seams that your ng-templates are not found, you are getting 404 on 'templates/login.html'. When you are using $stateProvider you need to put ui-view to show/display your content. I have modify your plunker a little bit, move templates to a separate files and add ui-view, all it's working fine now, please check here.
I am trying to incorporate $firebaseAuth into my Ionic project. I used a sample example, logging in with Twitter (auth.$authWithOAuthPopup('twitter')), from the Firebase website and incorporated it into my Ionic Framework. The code is shown below.
I am using the following versions (everything is up to date as of today):
firebase 2.0.4
angularfire 0.9.1
ionic 1.0.0-beta.14 "magnesium-mongoose"
Clicking on the button "Login" correctly opens the popup window and I can login. After that, however, in the Ionic project nothing has changed, while actually being logged in. When I refresh my browser, then it shows my displayname and it also notifies me that I am correctly logged in.
I had the same "stickyness" when trying to incorporate the ui-router authentication of Firebase, also copying the code from the website. Moreover, I had to refresh for changes to be processed.
Why is there this delay? Isn't firebase supposed to be real-time? My guess is that it has to do something with the settings of Ionic, since using the Angularfire-seed (without Ionic) works perfectly fine. Or maybe its something else?
app.js
// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.services' is found in services.js
// 'starter.controllers' is found in controllers.js
angular.module('starter', ['ionic', 'firebase', 'starter.controllers', 'starter.services'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
// setup an abstract state for the tabs directive
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
// Each tab has its own nav history stack:
.state('tab.dash', {
url: '/dash',
views: {
'tab-dash': {
templateUrl: 'templates/tab-dash.html',
controller: 'DashCtrl'
}
}
})
.state('tab.chats', {
url: '/chats',
views: {
'tab-chats': {
templateUrl: 'templates/tab-chats.html',
controller: 'ChatsCtrl'
}
}
})
.state('tab.chat-detail', {
url: '/chats/:chatId',
views: {
'tab-chats': {
templateUrl: 'templates/chat-detail.html',
controller: 'ChatDetailCtrl'
}
}
})
.state('tab.friends', {
url: '/friends',
views: {
'tab-friends': {
templateUrl: 'templates/tab-friends.html',
controller: 'FriendsCtrl'
}
}
})
.state('tab.friend-detail', {
url: '/friend/:friendId',
views: {
'tab-friends': {
templateUrl: 'templates/friend-detail.html',
controller: 'FriendDetailCtrl'
}
}
})
.state('tab.account', {
url: '/account',
views: {
'tab-account': {
templateUrl: 'templates/tab-account.html',
controller: 'AccountCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/tab/dash');
});
services.js
angular.module('starter.services', [])
// let's create a re-usable factory that generates the $firebaseAuth instance
.factory("Auth", ["$firebaseAuth", function($firebaseAuth) {
var ref = new Firebase("https://cloakit.firebaseio.com/");
return $firebaseAuth(ref);
}])
controllers.js
// other controllers
// AccountCtrl
.controller("AccountCtrl", ["$scope", "Auth", function($scope, Auth) {
$scope.settings = {
enableFriends: true
};
$scope.auth = Auth;
$scope.user = $scope.auth.$getAuth();
}]);
tab-account.html
<ion-view view-title="Account">
<ion-content>
<ion-list>
<ion-item class="item-toggle">
Enable Friends
<label class="toggle">
<input type="checkbox" ng-model="settings.enableFriends">
<div class="track">
<div class="handle"></div>
</div>
</label>
</ion-item>
<ion-item>
<div ng-show="user">
<p>Hello, {{ user.twitter.displayName }}</p>
<button ng-click="auth.$unauth()">Logout</button>
</div>
<div ng-hide="user">
<p>Welcome, please log in.</p>
<button ng-click="auth.$authWithOAuthPopup('twitter')">Login</button>
</div>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- firebase js -->
<script src="lib/firebase/firebase.js"></script>
<script src="lib/firebase/angularfire/angularfire.min.js"></script>
<!-- loading bar -->
<script src="lib/angular-loading-bar/src/loading-bar.js"></script>
<link href='lib/angular-loading-bar/src/loading-bar.css' rel='stylesheet' />
<!-- cordova script (this will be a 404 during development) -->
<script src="lib/ngCordova/dist/ng-cordova.js"></script>
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="starter">
<!--
The nav bar that will be updated as we navigate between views.
-->
<ion-nav-bar class="bar-stable">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<!--
The views will be rendered in the <ion-nav-view> directive below
Templates are in the /templates folder (but you could also
have templates inline in this html file if you'd like).
-->
<ion-nav-view></ion-nav-view>
</body>
</html>
You might want to take a look at $onAuth.
$onAuth Listens for changes to the client’s authentication state.
So your code would look like:
$scope.auth = Auth;
var authData = $scope.auth.$getAuth();
$scope.auth.$onAuth(function(authData) {
if (authData) {
$scope.user = authData
} else {
console.error("Could not retrieve user");
}
});
You may need to run a $scope.$apply(). I'm thinking you won't since $firebase should be within Angulars digest cycle, but I would throw one in there if it still doesn't work just to be sure you don't need it
ngRoute not working while no errors are reported to console .
given no errors to console, how is it possible to follow execution of ngRoute procedures ?
i saw examples using $locationProvider.html5Mode(true), i don't understand when that should be used but i don't think it is required to make ngRoute work.
index.html has navigation links and ngView :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="bower_components/angular/angular.js"> </script>
<script src="bower_components/angular-route/angular-route.js"> </script>
<script src="main.js"> </script>
</head>
<body ng-app="Main">
<ul>
<li> first partial </li>
<li> second partial </li>
</ul>
<div ng-view></div>
</body>
</html>
main.js defines the router and the controllers :
var Main = angular.module('Main', ['ngRoute']);
function router($routeProvider) {
var route = {templateUrl: 'partials/default.html'};
$routeProvider.when('', route);
route = {
templateUrl: 'partials/first.html',
controller: 'first'
};
$routeProvider.when('content/first', route);
route = {
templateUrl: 'partials/second.html',
controller: 'second'
};
$routeProvider.when('content/second', route);
}
Main.config(['$routeProvider', router]);
Main.controller('first', function($scope) {
$scope.list = [1,2,3,4,5];
});
Main.controller('second', function($scope) {
$scope.list = [1,2,3];
});
partials simply make use of ngRepeat:
<header> First content </header>
<p ng-repeat="iter in list">
first
</p>
solved :
my problem was that my whole application is located under /ang/ prefix, and after adding that prefix to urls now it is working .
shouldn't there be a way to use relative urls ? i guess there should and i will try to fix it .
the problem is NOT with the different syntax as everyone suggested, and that is alarming to the fact many JS developer do not in fact understand the one line syntax that they are using everywhere .
Please check this code
HTML code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular-route.js"> </script>
<script src="script.js"> </script>
</head>
<body ng-app="Main">
<ul>
<li> first partial </li>
<li> second partial </li>
</ul>
<div ng-view></div>
</body>
</html>
Js file
var app = angular.module('Main', ['ngRoute']);
app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider.
when('/content/first', {
templateUrl: 'first.html',
controller: 'first'
}).
when('/content/second', {
templateUrl: 'second.html',
controller: 'second'
});
}]);
app.controller('first', function($scope) {
$scope.list = [1,2,3,4,5];
});
app.controller('second', function($scope) {
$scope.list = [1,2,3];
});
first page HTML
<header> First content </header>
<p ng-repeat="item in list">
{{item}}
</p>
here is your working code click
Do not reuse the route object as it might cause problems. Consider using it in the form (as suggested by the docs https://docs.angularjs.org/api/ngRoute/service/$route#example ):
$routeProvider
.when('content/second', {
templateUrl: 'partials/second.html',
controller: 'second'
});
If you want to debug the routes that angular goes through, you might want to look at angular's interceptors: https://docs.angularjs.org/api/ng/service/$http#interceptors
Also, $locationProvider.html5Mode(true) is not needed to make ngRoute work. It is simply a way of defining how the URLs should look like and work. in HTML mode you can change the links to not use # anymore and simply be www.yoursite.com/app/content/second instead of www.yoursite.com/app#content/second
your route configuration is not correct, you assume route function is execute for each and every link u click but its not.
so your route function should be like
function router($routeProvider) {
$routeProvider.
when('/content/first', {
templateUrl: 'partials/first.html',
controller: 'first'
}).
when('/content/second', {
templateUrl: 'partials/second.html',
controller: 'second'
}).
otherwise({
templateUrl: 'partials/default.html'
});
}
note that urls should be like <a href="#/content/first"> // note the slash after #
to match that the routes in route function should be like when('/content/first', { note the leading slash
here is the working Plunker
Define your Routes in routes.js
var route = angular.module('route', ['ngRoute']);
route.config(function ($routeProvider) {
$routeProvider
.when("/", {
templateUrl: "views/home.html",
controller : 'homeCtrl'
})
.when("/home", {
templateUrl: "views/home.html",
controller : 'homeCtrl'
})
.when("/product", {
templateUrl: "views/product-info.html"
})
.otherwise({redirectTo :'/'});
});
Attach the router to your Main Module.
angular.module('myApp', ['route']);
Import both the scripts in your index.html
I'm suffering a problem with ui-router when I add a wrong segment to the route.
An example... http://xxx.xxxxx.xxx/roles works fine. This is a route defined without parameters. But if I add another segment in the browse http://xxx.xxxxx.xxx/roles/kk the $urlRouteProvider.otherwise('/') does not work and the application is trying to load all web resources (css, html, javascript, etc.) from a route like http://xxx.xxxxx.xxx/roles/app/app.css returning a lot of errors in console.
This code is in my app.config:
$urlRouterProvider
.otherwise('/');
$locationProvider.html5Mode(true);
And this is an example of route definition:
angular.module('myApp')
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('roles', {
url: '/roles',
templateUrl: 'app/modules/admin/roles/index.html',
controller: 'RolesCtrl',
authenticate: true
})
.state('logs', {
url: '/logs',
templateUrl: 'app/modules/admin/logs/index.html',
controller: 'LogsCtrl',
authenticate: true
})
.state('parameters', {
url: '/parameters',
templateUrl: 'app/modules/admin/parameters/parameters.html',
controller: 'ParametersCtrl',
authenticate: true
});
}]);
Any help with this behavior?
Regards
Jose
Not fully sure where is theissue here... but I created working plunker, which should help to see what is needed to see the HTML 5 and ui-router working together. In case that server side is configured properly, this should work out of the box. Please, check this firstly:
How to: Configure your server to work with html5Mode
Now, this would be adjusted state def, to show the deep url nesting:
$stateProvider
.state('roles', {
url: '/roles/:id',
...
})
.state('roles.logs', {
url: '/logs',
...
})
.state('roles.logs.parameters', {
url: '/parameters',
...
});
To make all these call below wroking:
<nav>
roles/11/<br />
roles/22/logs<br />
roles/33/logs/parameters<br />
</nav>
<nav>
<a ui-sref="roles({id:1})">roles </a><br />
<a ui-sref="roles.logs({id:2})">roles.logs</a><br />
<a ui-sref="roles.logs.parameters({id:3})">roles.logs.parameters</a><br />
</nav>
we have to not forget to properly set the base url, in our example:
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
...
<base href="/cTRk4o9HRELCQ4OK/" />
But for plunker we should set that dynamically:
<script>
document.write('<base href="'+ document.location.pathname +'" />')
</script>
Check working example here
You also have to define an state that points to the otherwise url, this way UI Routers knows how to handle the default state.
var app = angular.module('demo', ['ui.router']);
app.config(function($stateProvider, $urlRouterProvider){
$stateProvider
.state('roles', {
url: '/roles',
templateUrl: 'roles.html'
})
.state('otherwise', {
url: '/',
templateUrl: 'otherwise.html'
})
$urlRouterProvider
.otherwise('/');
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://rawgit.com/angular-ui/ui-router/0.2.11/release/angular-ui-router.js"></script>
<div ng-app="demo">
<ul>
<li>Roles</li>
<li>Otherwise</li>
<li>Not Found</li>
</ul>
<ui-view></ui-view>
<script type="text/ng-template" id="roles.html">
<h2>Roles Template</h2>
</script>
<script type="text/ng-template" id="otherwise.html">
<h2>Otherwise Template</h2>
</script>
</div>
I am using ui-router for my router. I want to implement i18n and for it I've created the following states
$stateProvider
.state('main', { url: '/:lng', abstract: true, template: '<div ui-view></div>'})
.state('main.index', { url: '/', templateUrl: '/views/index.html'})
.state('main.gallery', { url: '/gallery', templateUrl: '/views/gallery.html', controller: 'GalleryCtrl'})
And created the following links
a(ui-sref='main.index') Home
a(ui-sref='main.gallery') Gallery
However this links look like:
for index //
for gallery //gallery
I have found out that in uiSref directive he cannot inherit params from abstact main state.
Am I doing wrong with states?
Upadate:
I have one problem. I binded params to the scope object. In the ui-sref directive there is a watcher that tracks the params change, but in the handler of the watcher there is the following checking
if (newVal !== params) update(newVal);
However, when I try to debug the params is changing to the new param (I actually don't understand how, because params is assigned only once) and in the if check newVal === params
params = $scope.$eval(attr.params) //something like this
I even tried to use Object.observe on param object but it doesnot trigger before "watch" handler is triggered.
Now, I changed if check to make my code work.
There's nothing wrong with your state definitions from what I gather, but you're not passing any parameters to your ui-sref? Your state main.index & main.gallery still expect you to give it.
Working plunkr: http://plnkr.co/edit/uaII8LkMKoAHnacrLybQ?p=preview (Launch it seperate window to see url changes)
HTML:
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#*" data-semver="1.2.14" src="http://code.angularjs.org/1.2.14/angular.js"></script>
<script data-require="ui-router#*" data-semver="0.2.8" src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<h1>Hello Plunker!</h1>
</body>
<a ui-sref='main.index({lng:5})'>Home</a> <br/>
<a ui-sref='main.gallery({lng:5})'>Gallery</a>
</html>
JS:
// Code goes here
angular.module("app", ["ui.router"]).config(["$stateProvider",
function($stateProvider) {
$stateProvider
.state('main', {
url: '/:lng',
abstract: true,
template: '<div ui-view></div>'
})
.state('main.index', {
url: '/',
template: '<span>Index</span>'
})
.state('main.gallery', {
url: '/gallery',
template: '<span>Gallery</span>',
})
}
]);