I am working in MEAN stack. For my front-end, I am trying to render data of single item from my item list with angular. When I click the item, the URL changes to other than I have set and I don't get the data. I was able to see this only after using debugging mode. The expected link is /item/:itemid but I am getting /item/partials/item.html I have used the following files:
main.route.js (only route with problem shown)
function config($routeProvider, $locationProvider) {
$routeProvider
.when('/item/:itemid', {
templateUrl: 'partials/item.html',
controller: 'productCtrl',
controllerAs: 'vm'
})
.otherwise({redirectTo: '/'});
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
};
myData.service.js
angular
.module('myApp')
.service('myData', myData);
function myData ($http) {
var itemById = function (itemid) {
return $http.get('/api/items/' + itemid);
};
return {
itemById : itemById
};
}
product.controller.js
angular
.module('myApp')
.controller('productCtrl', productCtrl)
function productCtrl($routeParams, myData) {
var vm = this;
vm.itemid = $routeParams.itemid;
myData.itemById(vm.itemid)
.success(function(data) {
vm.data = { item : data };
vm.pageHeader = {
title: vm.data.item.name
};
})
.error(function (e) {
console.log(e);
});
};
items.html (link to single item page)
<a href='/#/item/{{ item._id }}'>{{ item.name }}</a>
item.html
<div ng-controller='productCtrl'>
<div class='container'>
<page-header content='vm.pageHeader.title'></page-header>
</div>
</div>
Forgive me if the question doesn't make much sense as I am new to this. Thanks in advance!
Remove the slash on this anchor below:
<a href='#/item/{{ item._id }}'>{{ item.name }}</a>
Related
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>
heres my code, i try to show my selected product form my product page by id.
for example when i click a product it go to right url like /#/product/2 and it show all the attribute of product id:2. please take a look this code
app.js
angular
.module('app', [
'ui.router',
'app.directives.productCard'
])
.config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'templates/pages/home.html',
controller: 'homeCtrl'
})
.state('product', {
url: '/product',
templateUrl: 'templates/pages/product.html',
controller: 'productCtrl'
})
.state('productDetails', {
url: '/product/:id',
templateUrl: 'templates/pages/productDetails.html',
controller: 'productDetailsCtrl'
})
}])
my services
angular
.module('app')
.factory('Product', ['$http', function($http) {
return {
get: function() {
return $http.get('https://raw.githubusercontent.com/vicariosinaga/learn/master/products.json').then(function(response) {
return response.data;
});
}
};
}])
productCtrl
angular
.module('app')
.controller('productCtrl',['$scope', 'Product', function($scope,Product) {
$scope.title="List Product";
Product.get().then(function(data) {
$scope.products = data;
});
$scope.products=Product.get();
}]);
productdetailsCtrl
angular
.module('app')
.controller('productDetailsCtrl',['$scope','$stateParams', 'Product', function($scope,$stateParams,Product){
$scope.id=$stateParams.id;
Product.get().then(function(data) {
var singleProduct = data.filter(function(entry){
return entry.id === $scope.id;
})[0];
console.log(singleProduct);
console.log($stateParams);
});
}]);
product.html
<div class="col-lg-3 col-md-4 col-sm-6">
<div class="card">
<img class="card-img-top" ng-src="{{item.image}}" alt="{{item.name}}">
<div class="card-block">
<strong class="card-title">{{item.name}}</strong>
</div>
<div class="card-block">
Buy
</div>
</div>
</div>
product detail.html
<p>{{id}}</p>
<p>{{name}}</p>
<p>{{image}}</p>
after all this code,when i try to check via console. i get Object {id: "2"}, but when i try to show all the attribute from product 2 i get on console undefined. why i got undifined. yeah i didnt use and local server. but if its the problem. does all the code is right to print all the attribut of product 2
here the link of the json https://raw.githubusercontent.com/vicariosinaga/learn/master/products.json
Change product details state url to make id parameter as a int which will allow you to pass return entry.id === $scope.id;(strict equality check).Here you have id value as string which makes singleProduct as undefined.
.state('productDetails', {
url: '/product/{id:int}',
templateUrl: 'templates/pages/productDetails.html',
controller: 'productDetailsCtrl'
})
otherwise you have to change your strict check to return entry.id == $scope.id;
I am using UI Router and UI Bootstrap in my Angular app. I'd like to use a service so that I can display alert messages from various controllers. I want the alert to display at the top of the screen. Any suggestions on how to modify the code below so that the alert will display at the top of the page and display messages from different controllers?
I'm using this Stack Overflow post as a model.
HTML:
<alert ng-repeat="alert in allInfos()" type="{{alert.type}}" close="closeAlert($index)"
ng-cloak>{{alert.msg}}</alert>
Service:
.factory('Informer', function(){
var messages = [];
var Informer = {};
Informer.inform = function(msg, type) {
messages.push({
msg: msg,
type: type
});
};
Informer.allInfos = function() {
return messages;
};
Informer.remove = function(info) {
messages.splice(messages.indexOf(info), 1);
};
return Informer;
})
Controller:
.controller('PaymentFormCtrl',
function ($scope, $http, Informer) {
$scope.handleStripe = function () {
Informer.inform("There was a problem authorizing your card.", "danger");
$scope.messages = 'problem';
$scope.allInfos = Informer.allInfos;
$scope.remove = Informer.remove;
}
};
});
.controller('ContactFormCtrl',
function ($scope, $http, Informer) {
//. . .
Informer.inform("There is already an account with that email address", "danger");
$scope.messages = 'problem';
$scope.allInfos = Informer.allInfos;
$scope.remove = Informer.remove;
}
};
});
Routers:
.state('home', {
url: '/',
views: {
'top': {
templateUrl: 'views/bigHero.html'
},
'bottom': {
templateUrl: 'views/home.html',
controller: 'HomeCtrl'
}
}
})
.state('payment', {
url: '/payment',
views: {
'top': {
templateUrl: 'views/customerinfo.html',
controller: 'ContactFormCtrl'
},
'bottom': {
templateUrl: 'views/creditcard.html',
controller: 'PaymentFormCtrl'
},
}
});
});
You really have three good options that I can think of off the top of my head.
Create a global or what i like to call a "RootController" of your application bound higher up in your DOM so that the other controllers scope naturally extends it. i.e.:
<div ng-controller="RootController">
<div ui-view></div>
</div>
You can create a parent state with UI Router that both your child states inherit, giving a similar effect to the case above:
$stateProvider.state('parent', {controller: 'ParentController'});
$stateProvider.state('parent.child1', {controller: 'Child1Controller'});
$stateProvider.state('parent.child2', {controller: 'Child2Controller'});
You can pass all shared functionality through a service, which acts as an error message to your necessary controllers.
myService.service('errorService', function() {
this.errorMessage = 'Everything is happy!';
});
myService.controller('PaymentFormCtrl', function($scope, errorService) {
$scope.errorService = errorService;
$scope.setError = function() {
errorService.errorMessage = 'An error happened!';
};
});
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');
})
Trying to show hide menus based on user login using a custom directive. It all works fine in the views templates but in header it does not work [header is a different template]. It works fine on page refresh though.
header.html
<div id="header" class="navbar">
<a class="navbar-brand" href="#">My APP</a>
<ul class="nav nav-pills">
<li has-logged="!in">Sign Up</li>
<li has-logged="in">Home</li>
</ul>
</div>
has-logged directive
angular.module('myApp')
.directive('hasLogged', function(CookieService) {
return {
link: function(scope, element, attrs) {
if(!_.isString(attrs.hasLogged))
throw "hasLogged value must be a string";
var value = attrs.hasLogged.trim();
var notLoggedFlag = value[0] === '!';
if(notLoggedFlag) {
value = value.slice(1).trim();
}
function toggleVisibilityBasedOnLogin() {
var logged = CookieService.getLoginStatus();
if(logged && !notLoggedFlag || !logged && notLoggedFlag)
element.show();
else
element.hide();
}
toggleVisibilityBasedOnLogin();
}
};
});
app.js config
var myApp = angular.module('myApp',['ngRoute','ngCookies']);
myApp.config(function ($routeProvider,$httpProvider) {
$routeProvider
.when('/', {
templateUrl: 'app/module/public/index.html',
header: 'app/partials/header.html',
footer: 'app/partials/footer.html'
})
.when('/login', {
templateUrl: 'app/module/login/login.html',
header: 'app/partials/header.html',
footer: 'app/partials/footer.html'
})
.when('/home', {
templateUrl: 'app/module/home/home.html',
header: 'app/partials/header.html',
footer: 'app/partials/footer.html'
})
.when('/register', {
templateUrl: 'app/module/register/register.html',
header: 'app/partials/header.html',
footer: 'app/partials/footer.html'
})
.otherwise({redirectTo: '/'});
});
Code to add header and footer on app run
// Adds Header and Footer on route change success
$rootScope.$on('$routeChangeSuccess', function (ev, current, prev) {
$rootScope.flexyLayout = function(partialName) { return current.$$route[partialName] };
});
I tried this POST solution but still the same effect.
How do i change the menus without page refresh??
You may look into ui-router. It supports multiple and nested views.
Demo Fiddle
Click on First and Second to navigate between both states.
Here is the basic setup
First you need the views:
<div ui-view="header"></div>
<div ui-view="content"></div>
<div ui-view="footer"></div>
Then some sort of navigation to switch between ui states:
<ul>
<li>First</li>
<li>Second</li>
</ul>
Here is a basic state configuration:
myApp.config(function($stateProvider, $urlRouterProvider) {
// default route
$urlRouterProvider.otherwise("/first");
// ui router states
$stateProvider
.state('first', {
url: "/first",
views: {
header: {
template: '<h1>First header</h1>',
controller: function($scope) {}
},
content: {
template: '<p>First content</>',
controller: function($scope) {}
},
footer: {
template: '<div>First footer</div>',
controller: function($scope) {}
}
}
})
.state('second', {
url: "/second",
views: {
header: {
template: '<h1>Second header</h1>',
controller: function($scope) {}
},
content: {
template: '<p>Second content</>',
controller: function($scope) {}
},
footer: {
template: '<div>Second footer</div>',
controller: function($scope) {}
}
}
});
});