Angular: passing object to different view in same controller - javascript

I am working on an Ionic app where, I need to pass an item (json object) to a view and bind the items there.
I've gone through a lot of similar questions, likely:
Unable to access $scope variable within same controller
AngularJS: Pass an object into a state using ui-router
But, seems like none is working in my case.
Here is my HTML markup of index.html page (from where I'm passing item):
<div class="list card slide-in" ng-repeat="item in posts track by $index">
<h2 ng-bind="item.title" class="assertive"></h2>
//comes inside ng-repeat loop; I'm passing the whole json object as parameter to next view
<button class="button button-full" ng-click="getPostDetail(item);"> Read More </button>
</div>
Html Markup of posts.html page (where I need to access item):
<ion-view view-title="Read More ">
<ion-content class="card-background-page ">
<div class="list padding-20">
<h2 ng-bind="selectedPost.title" class="assertive"></h2>
</div>
</ion-content>
</ion-view>
My Config:
app.config(function ($stateProvider, $urlRouterProvider, localStorageServiceProvider) {
$stateProvider
.state('tabs.posts', {
url: "/posts",
params: {
obj: null // as per other suggestion, added a param here
},
views: {
'home-tab': {
templateUrl: "templates/post.html",
controller: 'main'
}
}
})
My Controller:
app.controller('main', function ($scope, $http, $state, $ionicModal, $location, $stateParams, localStorageService) {
$scope.getPostDetail = function (data) {
var selectedPost = data;
$state.go("tabs.posts", { obj: selectedPost });
}
})
On click of button, the Posts View loads successfully, but no content is bound i.e. the view is blank

Unless I'm missing something, selectedPost needs to be on $scope. Otherwise it cannot be accessed from the view. So something like this.
$scope.getPostDetail = function (data) {
$scope.selectedPost = data;
$state.go("tabs.posts", { obj: selectedPost });
}

Related

Pulling list item data through to a new view created by the scope data

Although there are a few of these questions rocking about, none of them seem to have a good working example and i cant seem to figure out how to apply it to my project.
What i want to do is pull the data through from the list item into another view to use as a profile page.
JS
var app = angular.module('passDataDemo', ['ngRoute']);
// Configure our routes
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
// Route for the global controller
.when('/', {
templateUrl: 'list.html'
})
// Route for profile
.when('/:item.firstname', {
templateUrl: 'listItemProfile.html'
})
// Fallback
.otherwise({
redirectTo: '/'
});
}]);
// Main controller
app.controller('mainCtrl', ['$scope', '$http', function($scope, $http) {
$http.get('items.json').success(function(data) {
$scope.items = data;
});
}]);
View 1 html
<ul ng-repeat="item in items">
<li>
<p>{{item.firstname}}</p>
<p>{{item.surname}}</p>
<button ng-click="viewTheProfileView()">View Profile</button>
View 2 html
<h1>ITEM PROFILE</h1>
<p>{{item.firstname}}</p>
<p>{{item.surname}}</p>
Here is my Plunker - https://plnkr.co/edit/gZj5gOZEcCOLNbdxwduw?p=preview
After looking at your plunker, I see that you are only using one controller for all of your views. Because of this, you would only need to set the value of $scope.item and it will show up in your listItemProfile.html. Therefore, I would change your button to pass in the current item to the controller: <button ng-click="viewTheProfileView(item)">View Profile</button>.
Then in your controller:
$scope.viewTheProfileView = function(item) {
$scope.item = item;
};
This will allow clicking the ITEM PROFILE button in index.html to display the correct information.

Angular 1: Change title depending on current route

How do I change title that is displayed outside of a controller scope depending on current controller provided by router? Basically, I have mainMenu controller that is loaded when specific route is called. However, outside of the view, there is partial included which is a header. I want to change output inside of a header depending on the current route. I added code structure below:
index.html
<div ng-include="'partials/header.html'"></div>
<div ng-view></div>
/partials/header.html
<header ng-controller="HeaderCtrl">
<h1>{{ currentTitle }}</h1>
</header>
/partials/main-menu.html
<div ng-controller="MainMenuCtrl">
</div>
Router
var TaskApp = angular.module('TaskApp', [
'ngRoute',
'taskAppControllers'
]);
TaskApp.config(['$routeProvider',
function($routeProvider){
$routeProvider.
when('/main-menu', {
templateUrl: "partials/main-menu.html",
controller: "MainMenuCtrl"
}).
otherwise({
redirectTo: "/"
});
}]);
Controllers:
var taskAppControllers = angular.module('taskAppControllers',[]);
taskAppControllers.controller('TaskAppCtrl',[function(){}]);
taskAppControllers.controller('DesktopCtrl',[function(){}]);
taskAppControllers.controller('MainMenuCtrl', ['$scope','$http',
function($scope, $http){
$http.get('data/main-menu.json?' + Math.random()).success(function(data){
$scope.mainMenuOptions = data;
});
$scope.currentTitle = "Main menu"
}]);
taskAppControllers.controller('HeaderCtrl', ['$scope',
function($scope){
//
}]);
You could add one more property with each route options, which will something like title
when('/main-menu', {
templateUrl: "partials/main-menu.html",
controller: "MainMenuCtrl",
title: 'Main Page'
}).
Then place $routeChangeSuccess(it gets fired when route changes are succeeded) event inside HeaderCtrl, and then do grab current route object and get title from it and set it to currentTitle scope variable
$scope.$on('$routeChangeSuccess', function(event, current) {
$scope.currentTitle = current.title;
});

Why the controller isn't called when I manually reload the page? And how to fix it?

I work with angular.js. I Have a list of item and when I click on one of them it should display a specific template.
Everything works if I'm using the app from the root (index.html) but after clicking an item, if I reload the page (with the modified URL), the controller isn't call even if I try to click on the same item again.
Here is my code:
config.js
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/building/:buildingName', {
templateUrl: 'views/building.html',
controller: 'buildingCtrl'
})
.otherwise({redirectTo: '/'});
}]);
townCtrl.js
app.controller('townCtrl', ['$scope', '$routeParams',
function ($scope, $routeParams) {
$scope.buildingsList = [{
name: 'Foo',
route: 'foo'
}, {
name: 'Bar',
route: 'bar'
}];
$scope.select = function (item) {
$scope.selected = item;
};
}
]);
buildingCtrl.js
app.controller('buildingCtrl', ['$scope', '$routeParams',
function ($scope, $routeParams) {
console.log($routeParams.buildingName);
}
]);
town.html
<div class="row" ng-controller="townCtrl">
<div class="col-md-3">
<div class="list-group">
<a ng-repeat="building in buildingsList"
ng-click="select(building)"
ng-class="{active: selected === building}"
class="list-group-item"
ng-href='#/building/{{building.route}}'>
{{building.name}}
</a>
</div>
</div>
<div class="col-md-9">
<div ng-view></div>
</div>
</div>
So, when I click on the item Foo the url became ~/#/building/foo, buildingCtrl displays 'foo' in the console and building.html is properly rendered in the page.
But if I reload the page manually (i. e. F5), the URL stays the same, building.html isn't displayed, and worst, if I click on 'Foo' again nothing append...
Could you help me to fix this ? I'm probably missing something on the route.
It looks that you use the townCtrl twice - once for town.html and once for building.html...
Maybe you have to introduce another controller for building or just use the template without one (if you don't need a controller for the building template).
Btw: there is a ui-sref attribute to simplify linking https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref

Controller being called twice in Ionic (AngularJS)

In my angular project the user accepts a EULA then get automatically redirected to their dashboard, however, on this redirect the DashboardController seems to be being called twice, the DashboardController is being called on the route itself, I have checked to see if I have accidently called it again in the template but I havn't. Below is my route & controller. It doesn't appear to matter if I access the URL directly or via the redirect on the EULA controller, I get the same result.
The routes
.config(function($httpProvider, $stateProvider, $urlRouterProvider) {
$httpProvider.interceptors.push('httpRequestInterceptor');
$urlRouterProvider.otherwise('/');
$stateProvider
.state('login', {
url: '/',
templateUrl: 'templates/login.html',
data: {
requireLogin: false
}
})
.state('eula', {
url: '/eula',
templateUrl: 'templates/eula.html',
data: {
requireLogin: true
}
})
.state('dashboard', {
url: '/groups',
templateUrl: 'templates/dashboard.html',
data: {
requireLogin: true
}
})
});
The controller:
App.controller('DashboardController', ['$scope', 'RequestService', '$state', '$rootScope', function($scope, RequestService, $state, $rootScope){
alert('test');
}]);
Any ideas?
ADDED MY HTML AS PER COMMENTS
index.html
<body ng-app="App">
<ion-nav-bar class="bar-positive nav-title-slide-ios7" align-title="center">
<ion-nav-back-button class="button-icon ion-arrow-left-c"></ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view class="slide-left-right"></ion-nav-view>
<ui-view></ui-view>
</body>
dashboard.html
<div class="groups" ng-controller="DashboardController">
<ion-view title="App">
<ion-nav-buttons side="right">
<a ui-sref="groupcreate"><span class="icon ion-ios-plus-outline"></span></a>
</ion-nav-buttons>
<ion-content class="padding">
<div class="row">
<div class="col-50" ng-repeat="group in groups">
{{ group }} 1
</div>
</div>
</ion-content>
</ion-view>
</div>
If you are using ui-router you don't have to use ng-controller. You have used it in your dashboard.html, another is generated by ui-router - that's why it is hit twice.
Ok so after a long time debugging and check stuff out, I found out that it was an issue relating to the Nav Bar in ionic, essentially, I was calling <ui-view></ui-view> & <ion-nav-view></ion-nav-view> on the same page, so basically doubling up on my views which in turn was calling the controller twice.
I know this has been answered already as well, but I wanted to add my fix for the exact same problem.
My controllers were also being called twice, but in my case I had to comment out the ng-controller settings in various files:
My config function in the main app.js
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('splash', {
url: "/",
templateUrl: "app/splash/splash.html"
// controller: 'SplashCtrl'
})
Since I was already calling it in the markup:
<ion-view view-title="TickerTags" ng-controller="SplashCtrl as splash">
<ion-content class="splash">
The controller key inside of my Directives
angular
.module('tagsPanelDirective', [])
.controller('TagsPanelCtrl', TagsPanelCtrl)
.directive('tagsPanel', tagsPanel);
function tagsPanel() {
var directive = {
templateUrl: "app/tags/tagsPanel.html",
restrict: "E",
replace: true,
bindToController: true,
// controller: 'TagsPanelCtrl as tagsPanel',
link: link,
scope: false
};
return directive;
function link(scope, element, attrs) {}
}
Again since I was already calling it from within the template markup:
<section class="tags-panel" ng-controller="TagsPanelCtrl as tagsPanel">

Angular.js $scope and controller again

I know there are many questions regarding the angular $scope by after a couple of hours I still can't figure out what is wrong. I'm using Angular.js with Ionic but the problem should be angular related.
In my App I need a "add to wishlist" function. In the productDetail view when someone tapps "add to wishlist" I add this product with a service and webSQL to the database. Now when the user goes to the wishlist view I get all saves products but the view doesn't update.
I have a file menu.html with an Ionic side-menu:
<ion-side-menu side="left" expose-aside-when="large" width="72">
<ion-content>
<ion-list ng-controller="LeftMenuCtrl">
<ion-item nav-clear menu-close ng-href="#/app/wish" ng-click="updateWishList()" ng-class="{'current': isActive('/app/wish')}">
<span class="icon icon-menu-wish"></span>
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
The "LeftMenuCtrl" handels the hover for the active menu item.
In my WishListView I would like to show the current added products:
File wishList.html
<ion-view hide-nav-bar="true" view-title="WISHLIST" ng-controller="WishlistCtrl">
<div class="bar bar-header bar-stable">
<div class="header-wrapper">
<!--heading-->
<div class="dash-slider-wrapper"" >
<div class="header-text-main">WHISH</div> <div class="header-text-sub">LIST</div>
</div>
</div>
</div>
<ion-content class="has-header">
<ion-item class="product-card" ng-repeat="product in products">
<div class="card">
EAN: {{product.ean}}
</div>
</ion-item>
</ion-content>
</ion-view>
And the controller:
app.controller("WishlistCtrl", function($scope, $state, productService) {
//gets called when the controller is loaded
productService.getWishlistProducts().then(function (products) {
$scope.products = products;
});
//gets called when the user clicks on the navi but does not
//update the $scope (or it updates the wrong $scope)
$scope.updateWishList = function () {
productService.getWishlistProducts().then(function (products) {
$scope.products = products;
});
};
})
Can anyone tell me whats wrong here please?
Edit:
This is the state for the menu link:
.state('app.wish', {
url: "/wish",
views: {
'menuContent': {
templateUrl: "templates/wish.html"
}
}
})
Edit2:
When I refresh the page, I see all added products. But not immediately. It's like the
$scope.updateWishList = function () ...
creates another $scope...
Edit3:
app.controller('ProductDetailCtrl', function($stateParams ,$state, $scope, productService, $ionicHistory, $ionicPopup) {
$scope.addToWishlist = function(ean) {
productService.addProductToWishlist(ean).then(function(response) {
if(response == "OK") {
var alertPopup = $ionicPopup.alert({
title: 'product added to wishlist',
template: 'You can go to your wishlist to see all your marked products'
});
}
});
};
})
Edit4:
I added a Plunker here: http://plnkr.co/edit/0woPfN
It´s not working but you can see the code there (I deleted unnecessary stuff)
Your problem is that you have 2 declaration of the WishlistCtrl.
Once in the app.js:
.state('app.wish', {
url: "/wish",
views: {
'menuContent': {
templateUrl: "wish.html",
controller: 'WishlistCtrl' //here is the first declaration
}
}
})
Second in the HTML:
<ion-view hide-nav-bar="true" view-title="WISHLIST" ng-controller="WishlistCtrl">
Remove either one and you'll be fine.
Finally, I got it working.
First in the StateProvicer I added a resolve method:
.state('app.wish', {
url: "/wish",
views: {
'menuContent': {
templateUrl: "templates/wish.html",
controller: 'WishlistCtrl',
resolve: {
products: function(productService) {
return productService.getWishlistProducts()
}
}
}
}
})
And to update the model when a new product gets added to the wishlist:
.controller("WishlistCtrl", function($scope, $state, productService, products) {
//set wishlist products on controller load
$scope.products = products;
//updated wishlist when a new product gets added
$rootScope.$on('updatedWishList', function() {
console.log('List has been updated. ');
productService.getWishlistProducts().then(function (products) {
$scope.products = products;
});
});
})
Easy... when you know how :D

Categories