How to pass data between pages in Ionic app - html

I have had a look at all the examples around and tried to integrate with my Ionic project and failed. Here is what I have so far.
I am using a project created using creator.ionic.com
I have an html page that im loading a JSON file into
(agentSchedule.html)
<ion-view style="" title="Agent Schedule">
<ion-content class="has-header" overflow-scroll="true" padding="true">
<ion-refresher on-refresh="doRefresh()">
</ion-refresher>
<div ng-controller="agentScheduleCtrl">
<ion-list style="">
<ion-item class="item-icon-right item item-text-wrap item-thumbnail-left" ng-repeat="user in users">
<img ng-src="{{ user.image }}">
<h2>{{ user.fname }} {{ user.lname }}</h2>
<h4>Role : {{ user.jobtitle }}</h4>
<h4>Username : {{ user.username }}</h4><i class="button-icon icon ion-ios-arrow-forward"></i>
</ion-item>
</ion-list>
</div>
</ion-content>
Here is the controller and routes for that page
.controller('agentScheduleCtrl', function($scope, $http, $timeout) {
var url = "http://www.otago.ac.nz/itssd-schedule/mobileappdevice/services/getUsers.php";
var url = "users.json";
$http.get(url).success( function(response) {
$scope.users = response;
});
.state('menu.agentSchedule', {
url: '/page4',
views: {
'side-menu21': {
templateUrl: 'templates/agentSchedule.html',
controller: 'agentScheduleCtrl'
}
}
})
I am another page that I want to pass the username to, and then use on any page that I go from there
(specificAgentDetails.html)
<ion-view style="" view-title="Agent Specific Schedule">
<ion-content class="has-header" overflow-scroll="true" padding="true">
</ion-content>
</ion-view>
Here is the controller and routes for that page
.controller('specificAgentDetailsCtrl', function($scope) {
})
.state('menu.specificAgentDetailsCtrl', {
url: '/page9',
views: {
'side-menu21': {
templateUrl: 'templates/specificAgentDetailsCtrl.html',
controller: 'specificAgentDetailsCtrl'
}
}
})
How to Pass the user.username JSON variable to the next page as a global variable ??
Any help would be awesome - im going around in circles

So what #shershen said is true most ionic apps are set up as SPA's, what you're going to do isn't a "ionic" thing it's more of a AngularJS thing. You're going to want to setup a Service to hold your User info and then share it with your other controllers.
Create a Factory to share the data.
Inject the factory into the first controller and set it.
Inject the factory into the second controller and retrieve it.
Share data between AngularJS controllers
If you're familiar with get/set in OOP you should have no problem.
.factory('Data', function () {
var user = {};
return {
getUser: function () {
return user;
},
setUser: function (userparameter) {
user = userparameter;
}
};
})
.controller('agentScheduleCtrl', function($scope, $http, $timeout, Data) {
var url = "http://www.otago.ac.nz/itssdschedule/mobileappdevice/services/getUsers.php";
var url = "users.json";
$http.get(url).success( function(response) {
Data.setUser(response);
$scope.users = response;
});
Then in your second controller:
.controller('specificAgentDetailsCtrl', function($scope, Data) {
$scope.user = Data.getUser();
})
Make sure the syntax between the view and controllers are correct. I'm using user you're using users, setup breakpoints in your controllers to see what's going on there.

I use a little generic factory to do the job.
.factory('LocalRepo', function () {
var data = {}
return {
Get: function (key) {
return data.key;
},
Set: function (key, val) {
return data.key = val;
}
}
})
.controller('One', function($scope, LocalRepo) {
//Set in first controller
//TODO: $scope.users = .... from your call
LocalRepo.Set('users', $scope.users);
})
.controller('Two', function($scope, LocalRepo) {
//Get in second controller
$scope.users = LocalRepo.Get('users');
})
Use it to set whatever you want between controllers

Here is a quite simple solution. use $window and it will hold the data globally available for all controllers, services or anything etc.
.controller('agentScheduleCtrl', function($scope, $http, $timeout,$windows) {
$window.users = [];
var url = "http://www.otago.ac.nz/itssd-schedule/mobileappdevice/services/getUsers.php";
var url = "users.json";
$http.get(url).success( function(response) {
$window.users = response;
});
})
Inject $window as dependency in other controller and you can access it like $window.users.
Hope it helps someone.

Related

Filter works but there is no change in UI. AngularJS

I am making an online food ordering site using AngularJS. What I want to do is change the filter by clicking on category tabs. This is my code:
shoppingCart.prototype.changeFilter = function (cat) {
var ref = document.getElementById("refresh");
category = cat;
}
My HTML looks like this:
<ul class="menu-filter-list list-inline margin-b-40 text-center">
<li>
<a ng-click="cart.changeFilter(null)" id="refresh">All</a>
</li>
<li data-filter=".{{product.category}}" ng-repeat="product in store.products | unique:'category'" >
<a ng-click="cart.changeFilter(product.category)">
{{product.category}}
<span></span>
</a>
</li>
</ul>
The filter is applied on ng-click="cart.changeFilter(product.category)"
UPDATE: controller.js
'use strict';
// the storeController contains two objects:
// - store: contains the product list
// - cart: the shopping cart object
function storeController($scope, $routeParams, DataService) {
// get store and cart from service
$scope.store = DataService.store;
$scope.cart = DataService.cart;
// use routing to pick the selected product
if ($routeParams.productSku != null) {
$scope.product = $scope.store.getProduct($routeParams.productSku);
}
}
app.js
'use strict';
// App Module: the name OnlineOrders matches the ng-app attribute in the main <html> tag
// the route provides parses the URL and injects the appropriate partial page
var storeApp = angular.module('OnlineOrders', ['ui']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/store', {
templateUrl: 'partials/store.htm',
controller: storeController,
}).
when('/products/:productSku', {
templateUrl: 'partials/product.htm',
controller: storeController
}).
when('/cart', {
templateUrl: 'partials/shoppingCart.htm',
controller: storeController
}).
when('/processing', {
templateUrl: 'partials/processingOrder.htm',
controller: storeController
}).
otherwise({
redirectTo: '/store'
});
}]);
// create a data service that provides a store and a shopping cart that
// will be shared by all views (instead of creating fresh ones for each view).
storeApp.factory("DataService", function () {
// create store
var myStore = new store();
// create shopping cart
var myCart = new shoppingCart("OnlineOrders");
myCart.addCheckoutParameters("Stripe", "pk_test_9iwiq8RA0aacvfi350h76350");
// return data object with store and cart
return {
store: myStore,
cart: myCart
};
});
I have added my controller.js and app.js.
Can anyone please help me figuring out why the UI is not changing?

Needed factory working in angular js

Actually i was new to angular js i am trying to call my factory operation into controller i dont know where i am going wrong
and my js goes here
app.factory("myFactory",function(){
var something = {};
something.getsum = function() {
$scope.service = " heloo people"
}
return something;
});
app.controller("helloController", function($scope,myFactory) {
$scope.clickme = function() {
$scope.service=myFactory.getsum();
}
});
and my html goes here
<div ng-controller="hello controller">
<button ng-click="clickme"></button>
<h2>{{service}}</h2>
</div>
and my config goes here:
$urlRouterProvider.otherwise("/index/utilise");
$stateProvider
.state('index', {
abstract: true,
url: "/index",
templateUrl: "display.html",
controller:'mainController',
controllerAs: "parentCtrl",
})
.state('index.sample', {
url: "/home",
templateUrl: "content/sample.html",
})
.state('index.utilise', {
url: "/utilise",
templateUrl: "content/utilise.html",
})
})
First issue is that to use the myFactory factory in your controller you would need to inject it into the controller via dependency injection:
app.controller("helloController", function($scope, myFactory) {
$scope.clickme = function() {
$scope.service = myFactory.getsum();
}
});
Second issue you would not use $scope in the myFactory factory method getsum(), you would simply return the value you need:
app.factory("myFactory",function(){
var something = {};
something.getsum = function() {
return " heloo people";
}
return something;
});
Third issue is ng-click was not actually execute controller function clickme as there was parenthesis () as you would with any JavaScript function. It should be ng-click="clickme()" to actually call the function on the controller:
<div ng-controller="helloController">
<button ng-click="clickme()"></button>
<h2>{{service}}</h2>
</div>
Finally, it's unclear what the structure of your application based on the ui-router configuration your provided. With ui-router you wouldn't really have the need to use ng-controller as you can specify what controller any given view should be using. I've created multiple Plunkers, one and two, demonstrating the factory functionality with and without controllers specified for child routes. This should be more than enough to demonstrating calling a controller function in different situations.
Hopefully that helps!

Dynamic routing in angularjs using single html page?

I'm working with an application in angular where I have items in an array, and when I click on each item, details should be displayed in details page,I want to achieve this by displaying details of all items in the same details page dynamically, how do I do this?
Here is my code
<body ng-app="myApp" ng-controller="mobileController">
search:<p><inpu type="text" ng-model="test"></p>
<ul>
<li ng-repeat="x in names | filter :test" >
<a href=#/> {{ x }}</a>
</li>
</ul>
<div ng-view></div>
var app = angular.module("myApp",[]);
app.controller('mobileController', function($scope) {
$scope.names = ['iphone', 'Moto', 'Oneplus'];
});
</body>
I want to display the details of iPhone ,moto,oneplus in same details page,when user clicks on iPhone iPhone details should be displayed and same for others.
Here's a plunkr on how to do what you want using UI-Router
You can use two states to do what you want by having two states: one for the list view and one for the details view.
$stateProvider
.state('items', {
url: '/',
controller: 'ItemsListCtrl',
templateUrl: 'items-list.html',
resolve: {
Items: function (ItemsService) {
return ItemsService.getAll();
}
}
})
.state('items.details', {
url: ':itemId/',
controller: 'ItemDetailsCtrl',
templateUrl: 'item-details.html',
resolve: {
Item: function (ItemsService, $stateParams) {
return ItemsService.getById($stateParams.itemId);
}
}
})
When someone clicks on an item you send them to a url with the itemId as a stateParam and resolve that item as you load the view within the view you have currently rendered (these are called nested/child views in ui-router).
Then in the controllers you just inject the items/item you resolved at the state level, and can manipulate them or assign them to your scope.
.controller('ItemsListCtrl', function ($scope, Items, $state) {
$scope.Items = Items;
$scope.viewItemDetails = function (item) {
$state.go('items.details', {itemId: item.id});
};
})
.controller('ItemDetailsCtrl', function ($scope, Item, $state) {
console.log(Item);
$scope.Item = Item;
$scope.closeDetails = function () {
$state.go('items');
};
})
I'd recommend checking out UI-Router's docs https://github.com/angular-ui/ui-router/wiki

Angular need to move working code into a partial or something to display under other page html

I have a Angular SPA in which things are working fine except that the business wants me to move the code from this link-group.html (which has its own controller, module etc..)
The URL with the code to put into a template or place the code underneath the other html code supervisors.html
URL for News that is in link-group.html that I need to move:
http://localhost:1337/doc-home/#/tips/2?paginatePage=1
File:
link-group.html
Location:
Then the location of where I needs to display (move to)
URL:
http://localhost:1337/doc-home/#/supervisors
File:
supervisors.html
Location:
Template? controller reference?
UPDATE
I want to take all the code from the link.group.html and move it to the supervisor.html page
However, there is specific code that is referring to the controller/module/database that is based on the URL
<div class="links-group" ng-repeat="group in groups" ng-show="!group.hidden">
<div ng-show="!edit" style="margin: 5px 0;">
<h3>{{ group.title }}</h3>
<div ng-show="edit === true">
<input style="margin: 5px 0" placeholder="title..." class="input" ng-model="group.title" />
UPDATE 2 per suggestion from OP
Current controller.js for supervisor.html
angular.module('supervisors')
.controller('SupervisorsCtrl',
function ($scope, UserService) {
UserService.get(function (err, user) {
$scope.user = user;
});
});
So in order to modify can I add another module underneath it?
angular.module('supervisors')
.controller('SupervisorsCtrl',
function ($scope, UserService) {
UserService.get(function (err, user) {
$scope.user = user;
});
});
angular.module('linkgroup', ['ng'])
.directive('linkgroup', function({{ dependencies of your controller here }}) {
return {
templateUrl: {{ url of the template, likely link-group.html }},
link: function($scope, $element, $attributes) {
// think of this as the controller of a directive
{{ code of your controller,
replace `this` with `$scope` if you used ControllerAs }}
}
};
});
Seems that there is NO module.js in the common folder, there is a directives.js and controller.js
However I see that with links folder there is this code
angular.module('links')
.controller('LinksCtrl', function ($scope, LinksService, SearchService, UserService, notify, $window, $location) {
$scope.message = "";
UserService.get(function (err, user) {
if (err) {
notify.error('Error getting current user.');
} else {
if (user.groups.WEB_ESO !== true) {
$location.path('/');
}
}
});
Sounds like you could get away with a directive that contains your link-group. Transformation is pretty straightforward (if you used $scope in your controller it's almost direct copy+paste):
angular.module('linkgroup', ['ng'])
.directive('linkgroup', function({{ dependencies of your controller here }}) {
return {
templateUrl: {{ url of the template, likely link-group.html }},
link: function($scope, $element, $attributes) {
// think of this as the controller of a directive
{{ code of your controller,
replace `this` with `$scope` if you used ControllerAs }}
}
};
});
Then in supervisors.html add <linkgroup></linkgroup> at the bottom.

pass parameters to angular js directive partial view

I have an MVC application using angularJS. I have a primary navigation and secondary navigation. I am using ngRoute for primary navigation. I made secondary navigation template a directive that I can use in all the other pages. The template used in the directive needs some input parameters.
Routing code:
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/SecondaryNavigation/1', {
templateUrl: 'administration/Page1',
resolve: {
SecNavItems: ["$http", function($http){
var navItems = $http.get('/Navigation/SecondaryNavigation', {params: { pageName: 'Administration'}});
navItems.success(function (data) {
return data;
});
}]
},
controller: 'AdminController'
})}]);
var AdminController = function ($scope, SecNavItems) {
$scope.secList = SecNavItems;
}
AdminController.$inject = ["$scope", "SecNavItems"];
myApp.controller("AdminController", AdminController);
Web method code:
[HttpGet]
public JsonResult SecondaryNavigation(string pageName)
{
Dictionary<string, string> secnavItems = new Dictionary<string, string>();
secnavItems.Add("1", "Item1");
secnavItems.Add("2", "Item2");
var navigationItemsJson = Json(secnavItems, JsonRequestBehavior.AllowGet);
return navigationItemsJson;
}
Page1 code is
<secondary-navigation></secondary-navigation>
My directive is defined as follows:
myApp.directive("secondaryNavigation", function () {
return {
restrict: 'E',
scope: {},
templateUrl: '/navigation/secondaryNavigation'
}
});
Partial view template:
<div style="height:100%; width:25%; background-color:#675c5c; color: white; float:left">
#foreach (KeyValuePair<int, string> navItem in secList)
{
#navItem.Value<br /><br />
}
</div>
<div style="height:100%; width:75%; float:right"></div>
When I run the application I do not see the Item1 and Item2 in the page instead I see {{object}}
Please advise what I am missing in passing the parameters to the template used in the directive.
Thank you.
Figured what went wrong.
I had to create a html template of secondary navigation. I then included the web service call in the admincontroller, set the object value to the webservice result and added it to the routeProvider. I then
set the scope to false in the directive.
Following are the changes I made.
Routing code:
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/SecondaryNavigation/1', {
templateUrl: 'administration/Page1',
controller: 'AdminController'
})}]);
var AdminController = function ($scope, $http) {
var navItems = $http.get('/Navigation/SecondaryNavigation', {params: { pageName: 'Administration'}});
navItems.success(function (data) {
$scope.secList = data;
});
}]
},
}
AdminController.$inject = ["$scope", "$http"];
myApp.controller("AdminController", AdminController);
My directive is defined as follows:
myApp.directive("secondaryNavigation", function () {
return {
restrict: 'E',
scope: false,
templateUrl: '/navigation/secondaryNavigation'
}
});