Ionic - Angular list detail linking - angularjs

I'm trying to make a Master-Detail module, but is not working. When I tap on the link that should go to the detail page, nothing happens, and in the console doesn't show any error. I'm working over a template created by Ionic Creator.
These are my controllers:
.controller('administraciNCtrl', ['$scope', '$stateParams','obtenerPerfiles', function ($scope, $stateParams,obtenerPerfiles) {
var initView = function(){
$scope.perfiles = obtenerPerfiles.query();
//console.log('Scope es:',$scope);
}
$scope.$on('$ionicView.loaded',function(){
initView();
});
}])
.controller('profesionalDetailCtrl', function ($scope, perfil) {
var initView = function(perfil){
$scope.perfil = perfil;
//console.log('Scope es:',$scope);
}
$scope.$on('$ionicView.loaded',function(){
initView();
});
})
This is the factory:
.factory('obtenerPerfiles', function($resource){
var getProfile = {};
getProfile.getPerfil = function(nombrePerfil){
/*I will use nombrePerfil later, first I wanna test it works*/
var datos;
datos = {"nombre": "yuyu","direccion":"carrera 11","perfil":"Administradorcita"};
return datos;
};
return $resource('bd/administracion.json', {}, { query: {method:'GET', isArray:true}});
});
This is the state:
.state('cONSTRYELO2.administraciN', {
url: '/page7',
views: {
'side-menu21': {
templateUrl: 'templates/administraciN.html',
controller: 'administraciNCtrl'
}
}
})
.state('cONSTRYELO2.profesionalDetail', {
url: '/perfilDetalle/:nombrePerfil',
views: {
'side-menu21': {
templateUrl: 'templates/profesionalDetail.html',
controller: 'profesionalDetailCtrl',
resolve:{
perfil: function($stateParams,obtenerPerfiles){
return obtenerPerfiles.getPerfil($stateParams.nombrePerfil);
}
}
}
}
})
And finally this is the HTML:
<ion-item class="item-icon-left item-icon-right" id="administraciN-list-item47" ui-sref="cONSTRYELO2.profesionalDetail({nombrePerfil:'{{perfil.nombre}}'})">
<i class="icon ion-android-globe"></i>3km
<span class="item-note">Ver más</span>
<i class="icon ion-android-add-circle"></i>
</ion-item>

Related

ng-repeat is not iterating

I have a little problem with ng-repeat.
I have a json file where is the data that I'm trying to display.
I wrote a little service to share the data. It has some methods to set and get the information but, when I try to use that methods in my controller to store the result in a variable (the one that I'm trying to iterate) it is like is were empty but, when I print the variable, print the result.
Here s my approach.
HTML
<ul class="list-unstyled products-list">
<li class="col-sm-6 col-md-3 product" ng-repeat="product in products">
<article>
<img ng-src="{{ product.img }}" class="img-responsive" alt="">
<div class="short-product-detail text-center">
<p class="name">{{ product.name }}</p>
<span class="price">{{ product.price }}</span>
</div>
add to cart
</article>
</li>
</ul>
controller
angular.module("Store")
.controller("ProductsCtrl", ["$scope", "productsService", function ProductsCtrl($scope, productsService) {
$scope.products = [];
productsService.fetchProducts()
.then(function(response) {
productsService.setProducts(response.data.products);
$scope.products = productsService.getProducts();
console.log($scope.products)
})
}])
service
angular.module("Store")
.service("productsService", ["api", "$http", function (api, $http) {
var productsList = [];
var categories = [];
var getProducts = function() {
return productsList;
};
var setProducts = function(products) {
productsList.push(products);
};
var getCategories = function() {
return categories;
};
var setCategories = function(categories) {
categories.push(categories);
}
var fetchProducts = function() {
return $http({
method: "GET",
url: api.url
});
}
return {
fetchProducts: fetchProducts,
getProducts: getProducts,
setProducts: setProducts,
getCategories: getCategories,
setCategories: setCategories
}
}])
main.js
angular.module("Store", ["ui.router"])
.constant("api", {
url: "data.json"
})
.config(function config($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
// Set up the states
$stateProvider
.state("products", {
url: "/",
views: {
"": {
templateUrl: "./templates/products.html",
controller: "ProductsCtrl"
}
}
})
})
Please, let me know what I'm doing wrong.
Thanks in advance guys
Problem is with your config, Change it like this
$stateProvider
.state('products', {
url: '/products',
templateUrl: './templates/products.html',
controller: 'ProductsCtrl'
})

Change login button to logout after oauth authentication

I am able to login successfully using outh 2.0 of google. The page redirects after proper authentication, but the problem is how do I set the login button to logout.
I tried with ng-if but it is not working. Previously, I have jwt token in localstorage and a boolean to change the login button status but with open authentication I am not able to change the button to "logout"
Here is the state provider:
myApp.config(function ($stateProvider, $urlRouterProvider, $httpProvider) {
// For any unmatched url, redirect to /login
$urlRouterProvider.otherwise("/Login");
var header = {
templateUrl: 'views/Header.html',
controller: function ($scope) {
}
};
var footer = {
templateUrl: 'views/Footer.html',
controller: function ($scope) {
}
};
// Now set up the states
$stateProvider
.state('Login', {
url: "/Login",
views: {
header: header,
content: {
templateUrl: 'views/Login.html',
controller: function ($scope) {
}
},
footer: footer
}
})
.state('LoggedIn', {
url: "/LoggedIn",
views: {
'header': header,
'content': {
templateUrl: 'views/LoggedIn.html',
controller: function () {
}
},
'footer': footer
},
data: {
requiresLogin: true
}
})
.state('AboutUs', {
url: "/AboutUs",
views: {
'header': header,
'content': {
templateUrl: 'views/AboutUs.html',
controller: function () {
}
},
'footer': footer
},
data: {
requiresLogin: true
}
})
.state('access_token', {
url: '/access_token={accessToken}&token_type={tokenType}&expires_in={expiresIn}',
views: {
'header': header,
'content': {
templateUrl: 'views/LoggedIn.html',
controller: function ($stateParams, $localStorage, $rootScope) {
var accessToken = $stateParams.accessToken;
if($stateParams.accessToken){
$localStorage.token = accessToken;
$rootScope.isLogin = true;
console.log("Token is: " + $localStorage.token);
}
}
},
'footer': footer
}
})
.state('ContactUs', {
url: "/ContactUs",
views: {
'header': header,
'content': {
templateUrl: 'views/ContactUs.html',
controller: function () {
}
},
'footer': footer
}
})
.state('SearchJobs', {
url: "/SearchJobs",
views: {
'header': header,
'content': {
templateUrl: 'views/SearchJobs.html',
controller: function () {
}
},
'footer': footer
}
});
$httpProvider.interceptors.push(['$q', '$location', '$localStorage', 'jwtHelper', function ($q, $location, $localStorage, jwtHelper) {
return {
'request': function (config) {
config.headers = config.headers || {};
if ($localStorage.token) {
var claims = jwtHelper.decodeToken($localStorage.token);
config.headers.Email = claims.email;
config.headers.Role = claims.role;
config.headers.Authorization = 'Basic ' + $localStorage.token;
}
// else{
// config.headers['Authorization'] = 'Basic ' + $localStorage.token;
// $http.defaults.headers.common['Authorization'] = 'Basic <username:pw>';
// }
return config;
},
'responseError': function (response) {
if (response.status === 401 || response.status === 403) {
$location.path('/Login');
}
return $q.reject(response);
}
};
}]);
});
And the html with ng-if:
<a href ng-if="isLogin" ng-click="logout()"><b>Logout</b></a>
<a href ng-if="!isLogin" class="dropdown-toggle" data-toggle="dropdown"><b>Login</b> <span class="caret"></span></a>
It's fine using ng-if like that, it just depends on if you want to have the element in your DOM or not.
First of all, don't use $rootScope for variables, because it can easily be overwritten by a other controller or something like that. And it's exposed in your whole app.
LoggedIn.html has the HTML, which you posted?
Make sure $stateParams.accessToken delivers true in any case.
Then try that in your controller (injecting $scope):
var accessToken = $stateParams.accessToken;
$scope.isLoggedIn = false;
if($stateParams.accessToken){
$localStorage.token = accessToken;
$scope.isLoggedIn = true;
}
In your HTML write something like:
<a href ng-if="isLoggedIn" ng-click="logout()"><b>Logout</b></a>
<a href ng-if="!isLoggedIn" class="dropdown-toggle" data-toggle="dropdown"><b>Login</b> <span class="caret"></span></a>
With ng-show/ng-hide:
<a href ng-show="isLoggedIn" ng-click="logout()"><b>Logout</b></a>
<a href ng-hide="isLoggedIn" class="dropdown-toggle" data-toggle="dropdown"><b>Login</b> <span class="caret"></span></a>

UI Router is not injecting resolved value into views at the same level

I have the following state configuration:
$stateProvider
.state('customer', {
url: '/customers',
templateUrl: 'app/components/customer/templates/main.tpl.html',
views: {
'list': {
templateUrl: 'app/components/customer/templates/list.tpl.html',
controller: 'ListCtrl as ctrl'
}
},
resolve: {
customerList: function ($stateParams, CustomerResource) {
console.log('trying to resolve');
var list = CustomerResource.list($stateParams);
return list;
}
}
})
Here is the main template:
<div class="container">
<div class="row">
<div ui-view="list" class="col-lg-4"/>
<div ui-view="details" class="col-lg-8"/>
</div>
</div>
I see on the console that angular is trying to resolve the dependency. But this dependency is never injected into the controller under views. What am I doing wrong here?
P.S. When I move views to some child state like customer.test the resolved dependency is injected as expected:
.state('customer.test', {
url: '/test',
views: {
'list#customer': {
templateUrl: 'app/components/customer/templates/list.tpl.html',
controller: 'ListCtrl as ctrl'
}
}
})
There is a working plunker
The problem here is not with resolve, but with the injection of the main template. This should be the state definition:
.state('customer', {
url: '/customers',
//templateUrl: 'app/components/customer/templates/main.tpl.html',
views: {
'': {
templateUrl: 'app/components/customer/templates/main.tpl.html'
},
'list#customer': {
templateUrl: 'app/components/customer/templates/list.tpl.html',
controller: 'ListCtrl as ctrl'
}
},
resolve: {
customerList: function ($stateParams, CustomerResource) {
console.log('trying to resolve');
var list = CustomerResource.list($stateParams);
return list;
}
}
})
so, with these in play:
.controller('ListCtrl', ['$scope', 'customerList', function ($scope, customerList) {
$scope.resolved = customerList
}])
.factory('CustomerResource', function(){
return {
list: function(params){return "Hello world"}
}
})
we can see that list view like this:
<div>
<h3>list view</h3>
{{resolved}}
</div>
will show Hello world
Check it here in action

Navigation and states inside ionic framework

i'm trying to make an app where the first time you use it I save some information locally. My purpose is that when the next times a person open the app it will be shown another page.
The problem is that I don't know how to load a simple page (not a part like a template) from my controller function.
Here my html
<body ng-app="starter" ng-controller="MainCtrl">
<ion-content class="center" [....]
<button class="button button-calm button-full button-clear button-large" ng-click="saveAll(name, job)">
<span style="font-size: 1.4em;">start</span>
</button>
</ion-content>
</body>
app.js
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state('home', {
url: "/home",
controller: "HomeCtrl",
template: "<h1>Home page</h1>"
})
$urlRouterProvider.otherwise('/first')
})
.controller('MainCtrl', function($scope, $localstorage, $location) {
$scope.setName = function(name) {
if (name) {
$localstorage.set('name', name.toLowerCase());
console.log(name);
}
}
$scope.getName = function() {
alert($localstorage.get('name'));
}
$scope.setJob = function(job) {
if (name) {
$localstorage.set('job', job.toLowerCase());
console.log(job);
}
}
$scope.getJob = function() {
alert($localstorage.get('job'));
}
$scope.saveAll = function(name, job) {
if (name) {
$localstorage.set('name', name.toLowerCase());
console.log(name);
}
if (job) {
$localstorage.set('job', job.toLowerCase());
console.log(job);
}
if (name && job) {
$location.path("home");
}
}
})
You can navigate routes using:
$location.path('/home');
or:
$state.go('home');
So.. in your MainCtrl you could put something like this:
$scope.getName = function() {
return $localstorage.get('name');
};
$scope.getJob = function() {
return $localstorage.get('job');
};
var init = function(){
if($scope.getName() && $scope.getJob()){
$location.path('/home');
}
};
init();
UPDATE:
Ionic has ui-router installed by default. ui-router documentation.
Each route accept a templateUrl property. I don't know which is you folder structure so you need to change them to work correctly:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
controller: 'HomeCtrl',
templateUrl: 'home/home.html'
})
.state('first', {
url: '/first',
controller: 'FirstCtrl',
templateUrl: 'first/first.html'
})
.state('second', {
url: "/second",
controller: "SecondCtrl",
templateUrl: 'second/second.html'
});
$urlRouterProvider.otherwise('/first');
})

angularjs nested detail view doesn't get displayed

the stateProvider of my app have a nested view (base.gallery -> base.gallery.detail) and if i click on a link inside my gallery it should show the detailview, but it doesn't...
the link looks good for me, but it only changes the url in the browser and it logs "get displayed" from the onEnter-function, but it doesn't display the template("modules/album/detail/view/detail.html") in my ui-view...
e.g.: for my link <a ui-sref="base.photos.detail(params(item.id))" class="list-item-link" href="/gallery/21/detail/457">
.state("base", {
abstract: true,
templateUrl: 'modules/base/views/base.html',
controller: function($scope, navigationData){
$scope.navigation.data = navigationData;
},
resolve:{
navigationData:function(navigationSvc){
var response = navigationSvc;
return response;
}
}
})
.state("base.categories", {
url: "/categories",
templateUrl: "modules/album/list/view/list.html",
controller: function($scope, data){
$scope.settings.data = data;
$scope.settings.type = "categories";
},
resolve:{
data:function(listSvc){
var response = listSvc.load("categories");
return response;
}
}
})
.state("base.category", {
url: "/category/:id",
templateUrl: "modules/album/list/view/list.html",
controller: function($scope, data){
$scope.settings.data = data;
$scope.settings.type = "galleries";
},
resolve:{
data:function($stateParams, listSvc){
var response = listSvc.load("category/"+$stateParams.id);
return response;
}
},
})
.state("base.gallery", {
url: "/gallery/:id",
templateUrl: "modules/album/list/view/list.html",
controller: function($scope, data, $stateParams){
$scope.settings.data = data;
$scope.settings.type = "photos";
},
resolve:{
data:function($stateParams, listSvc){
var response = listSvc.load("gallery/"+$stateParams.id);
return response;
}
}
})
.state("base.gallery.detail", {
url: "/detail/:photo_id",
templateUrl: "modules/album/detail/view/detail.html",
controller: function($scope, $stateParams){
console.log("doesn't get displayed ");
$scope.settings.type = "photo";
},
onEnter: function(){
console.log("get displayed");
}
})
html of my index where i load all my lists and i als want to display my detail view inside that ui-view...
...
<div class="content" ui-view></div>
...
html of my list view
<li class="list-item" ng-repeat="item in list.data">
<a ui-sref="{{state}}(params(item.id))" class="list-item-link">item.title</a>
</li>
UPDATE
k i got it ;) i need views and then use the # to target it in the same ui-view from my index.html
.state("base.gallery.detail", {
url: "/detail/:photo_id",
views:{
"#" : {
controller: function($scope, $stateParams, listSvc){
$scope.settings = {};
$scope.settings.type = "photos";
$scope.photo = listSvc.data[$stateParams.id_photo-1];
console.log($stateParams);
},
template: "<h2>detail</2><div>{{photo.title}}</div>"
}
});

Resources