How to manage data from one page to another in AngularJs? - angularjs

I am facing problem to manage the data while redirecting from one page to another in angulrJS.
I have one page (Tyre Card) where few fields like Name, address, isPersonalUser etc... From this page user can go into another page (Vehicle card) where few fields like regNo, vehicle type etc...
Two different controllers are there. Tyre Card and Vehicle card are linked using FK.
When user do some changes into TyreCard and navigate to another page(Vehicle card). I want to manage data of Tyre card, so when user back to this page from vehicle card then those data should be there on Tyrehotelcard.

angular.module('ContentApp').run(function ($rootScope) {
$rootScope.TyreCard = null;
})
})();
angular.module('ContentApp')
.controller('ContentCtrl', ContentCtrl)
ContentCtrl.$inject = ['$scope', '$rootScope', 'api'];
function ContentCtrl($scope, $rootScope, api) {
$rootScope.TyreCard=typecard
}

AngularJS is Single Page Application(SPA). So the idea of the angular application is to design an application with only one page.
So you cannot pass data from one page to another.
What you can use is partials and use ngRoute to navigate from one partials to another within the same page.
See ngRoute documentation

In case you're application is a single page app, the most common solution is to use a Factory (single instance) injected to both controllers, as described here:
Share data between AngularJS controllers

I found the solution. I will use sessionstorage.
Tyre Card data stored here.
vm.createSessionStorage("TyreHotelCardData", vm.data);
When I will back from vehicle page to Tyre card page.
var result = vm.getSessionStorage("TyreHotelCardData");
So in result I will have the Tyrecard data.

Related

Angular js - echoing data across multiple html pages

I've worked with many languages and environments (predominately iOS & C#) and have always managed to avoid working with scripting languages. That avoidance streak has come to an abrupt end: as a huge angularjs project was thrown in my lap - now I'm scrambling to understand this very strange world. Some features are really cool, other techniques have me thoroughly baffled. I've spent weeks reading tutorials, studying examples and I still cannot solve a relatively simple problem regarding best practices and structure of the code.
This is what I need to do: I have a form, where the user will input data (for argument's sake, its two fields of number type.) I need to have a banner at the top of the page with the sum of the two input fields - that by itself is relatively easy - but the problem for me, is repeating this banner on subsequent pages.
Home page will contain links to:
page 1
page 2
The link to page 2 will not be available until the user inputs data on page 1, forcing the user to visit page 1, first. The banner element needs to be a separate file. Page 2 is a passive display of the data, Page 1 is only page that can actively edit the data.
page 1: would look like this --
banner.html (sum of fields A & field B)
input field A
input field B
page 2:
banner.html (sum of field A & field B)
Lorem Ipsum ....
What's the best way to achieve this task?
You can have an index page with the banner on top, and partials using the same controller. The value of the banner will be a controller variable.
To use partials, inside the index page, you'll need to include the ngRoute module, and the script tag linking to it.
You'll have a div like this.
<div ng-view=""></div>
You'll have a partialRoutes.js file looking something like this.
myApp.config(function($routeProvider){
$routeProvider
.when('/',{
templateUrl: './partials/things.html'
})
.when('/stuff',{
templateUrl: './partials/stuff.html'
})
.when('/otherstuff',{
templateUrl: './partials/otherstuff.html'
})
.otherwise({
redirectTo: '/',
})
});
When you include ngRoute it will look something like this.
var myApp = angular.module('myApp', ['ngRoute']);
Here are the docs for ngRoute. Hope I helped.
https://docs.angularjs.org/api/ngRoute
Personally, I would have a service, lets call it userData. Your inputController would then write the details of the inputs to the userData service.
Your bannerController would then be notified of changes to the data in the userData service (via $watch or $broadcast)
This way when you switch pages the bannerController should not change and will still display this information
Notes:
This relies on you using some kind of AngularJS routing technique such as NGroute or UI Router. If a hard page navigation is made then the userData will have to be stored server side.
It would probably be better for the banner to stay outside any ui-view so that it is unaffected by navigation, but if it is then as the userData service will still be alive and holding the correct data when it is recreated it will have access to the same data
If both pages have same controller, then $scope can be used to achieve this. If pages have different controller, $rootScope can be used to share variables.

AngularJS, single controller or multiple controllers for ng-included views?

I have a dashboard page. Say it is Student dashboard and it has lots of details about the student like his personal details, course details, project details and etc. Inside student.html personal-details.html, course-details.html,project-details.html are included using ng-include.
Student can view those details as well as they can edit it. For this functionality, I have written a single controller StudentController as follows,
(function(){
"use strict";
angular.module('myApp')
.controller('StudentController',StudentController);
StudentController.$inject=['StudentService'];
function StudentController(StudentService){
var vm = this;
vm.studentData = null;
vm.editPersonalDetails = editPersonalDetails();
vm.editCourseDetails = editCourseDetails();
activate();
function activate(){
StudentService.getStudent().then(queryStudentCompleted);
}
function queryStudentCompleted(res){
vm.studentData = res.data;
}
function editPersonalDetails(){
StudentService.editPersonalDetails(vm.studentData);
}
function editCourseDetails(){
StudentService.editCourseDetails(vm.studentData);
}
}
In my real application there are lots of panels to be shown and everything is editable.
1)Should I use different controller for different ng-included pages or single controller is enough(think that more than 7 htmls are included and every panel is editable)? if yes how do the child controllers(say personalDetailsController, courseDetailsController which have edit methods in it) get access to the vm.studentData which is received in the studentController? In Page I can directly show it using ControllerAs syntax, but when I edit it I need to send the edited values to the child controller..
2)Currently studentData has every details that should be shown in the page. Should I keep that in that way or I need to split the data as well into smaller chunks?

Maintain the values in Angular Views

I am new to Angular.js and i am facing problem in maintaining the JSON feed values in the view.
I am using different routers and when i launch the app it loads the home.html which in turns calls the homeCtrl and make an HTTP call and binds the data using ng-repeat ( in home.html ). If user clicks on the list item to brings them to detail.html ( kind of detail page ).
Now the problem i face is , on the detail page when user tabs the back button - the app goes to home.html and the homeCtrl again hits the webservice and bind the whole data once again. Which i feel is unwanted as the JSON datas was already collected on the 1st time page load itself.
How can i preserve the old data when user move back forth between different views so i no need to hit same call over and over.
Thanks and sorry if its really basic stuff.
How can i preserve the old data when user move back forth between
different views so i no need to hit same call over and over.
If you use the $http service to make the requests use the cache: true option to use the default angular cache as explained in the docs: https://docs.angularjs.org/api/ng/service/$http#caching
Here an example:
$http.get(url, { cache: true}).then(...);
You can also define your custom cache object through the $cacheFactory service: https://docs.angularjs.org/api/ng/service/$cacheFactory
If you want some more complete with expiration, size limit and other cool stuff try angular-cache: https://github.com/jmdobry/angular-cache
Hi I think that you need is create a factory or service;so in this way the controllers shared data between them.
Here's an example

(How) can a controller be active when its view is not visible?

If I understand correctly, a controller is generated when its view becomes active?
Meaning that if the view is not visible, the controller doesn't exist/isn't active?
Is there any way that I can make the controller active "in the background"?
I have an app which has two main tabs, one for vehicle tracking & the other for something else. Each of those tabs has several sub-tabs (suing UI-Router); in the case of the vehicle tracking, I have one tab for a google map & another to show a grid with street addresses.
Here's a pic of the desktop app which I am trying to re-implement in Angular:
Now, I am an Angular beginner, so maybe my design idea is flawed, but:
Both the map and the vehicle locations tab use the identical data pulled from a server, which is a list of GPS lat/long & timestamp.
It seemed to me that it would be wrong to have each of those tabs (controllers) fetching the same data, duplicating code.
So, I wanted to have a controller for the "Vehicle locations" tab, which would get the data and feed it to a service which the two map/Vehicle locations sub-tabs (controllers) could $watch.
Even if I were not looking at that "parent view" ("Vehicle locations", but at another ("Vehicle reports" or "Employee reports"), I would this data downloading & view updating to continue, so that when the user clicks the "Vehicle locations" tab, the information is already there & the user doesn't have to wait while the app goes to the server to fetch data & draw its view.
Question: can Angular work that way, or am I asking it to do something which is un-angular-ish? If so, what is the correct way to implement this? Should I duplicate the $http.get code and should I have the controllers fetching & updating their own data on $scope.$on('$viewContentLoaded'?
If you need a central point of access for data in your AngularJS app, the best way to achieve it is to encapsulate it in a provider (either a service or a factory). Fetch the data in your provider and implement getters, so that you can inject it in your controllers and ask for the data without duplicating code and requests.
yourApp.service('serviceName', [ '$http',
function($http) {
this.getData = function() {
return $http.get(...);
}
}
]);
yourApp.controller('controllerA', ['serviceName',
function(serviceName) {
serviceName.getData().then(function(data){
$scope.data = data;
});
}
]);
//the same for other controllers
There are some points you can consider for this app:
You can create a factory for data you intend to share and reuse. So maybe create a http factory to get the data from the server and then inject it to whichever controllers you need to. Also you can resolve incoming data with "resolved" in angularjs (an option in routes) to make sure it's available before the page renders.
If you are passing in data within controller to http.get then, inject the factory and use promises with the http method.

Angularjs scope not retaining value

Friends..
For my understanding of how routing works in Angular I have created a simple application. This application has only two pages:
1. The first page will display all rows of the employee table. Upon clicking on a particular row, second page will display a form with details of that employee.
The list that is displayed on the first page uses the following code:
<table>
<tr ng-repeat="employee in employees">
<td>{{employee.firstname}} - {{employee. address}}</td>
<td><span ng-click="getSingleEmployeeDetails(employee.id)">Edit</a></td>
</tr>
</table>
I am using the same controller for both these pages and this controller looks like below:
function EmployeeCtrl($scope,$http,Employee,$location,$routeParams) {
// Get all employee details
var data;
Employee.query().then(function(_data) {
$scope.employees = _data.data;
});
// Get Single Employee Details
$scope.getSingleEmployeeDetails = function(id) {
$scope.employee = scope.employees[id];
$location.path('/editemployee/' + id);
}
}
However the issue I am facing is that when the code gets routed to /editemployee/1
for some reason the $scope.employees looses its values.
In other words the form never gets populated with employee details.
What am I doing wrong here ?
This has to do with scoping. The employees are loaded into the EmployeeCtrl when it is instantiated. Once you perform a routing event in getSingleEmployeeDetails() that causes a different controller to load with a different $scope. A $scope that is separate from the $scope inside EmployeeCtrl. One easy way around this is to let EmployeeCtrl handle the functionality of loading/displaying all employees and a single employee without routing to a new controller. The pros here is that it makes it easier to share information, and you don't have to reload the single employee information when the user clicks on a single employee because you can share that information more easily. The con is that you don't get back button navigation to navigate between selections of single employees.
The other option is to let the SingleEmployeeCtrl reload the information when it navigates. The pro is you get back button access again, but the con is you load the information twice (once for loading the full list, and twice for loading the employee information again). This also allows the user to bookmark single employee records, but who bookmarks things anymore?
Others have already explained the fact that a new controller (and $scope) are created when you change routes. Also note that $scope.employees is populated asynchronously, when the promise is resolved. What is likely happening is that getSingleEmployeeDetails() is being called before the promise is resolved, so the employees array is empty.
To solve the problem, I suggest a different architecture.
You have two views/pages. Each view in Angular typically has its own controller. Models/data are typically stored in services, and an API to retrieve and manipulate those models/data is made available/public by the service. A controller just glues everything together: it injects the service(s) it needs, and then references only the models/data that the associated view needs.
So, even though your app is simple, I suggest the above approach: one service (which stores your employee objects), two controllers, two views. In particular, put the query() call into your service (so it will be called once, when the service is created) and store your data in the service. The service API should define functions/methods that return a promise that will eventually contain the desired data (list of employees, or just one). The controllers should use those methods to get a reference to the desired data.
See also Should services expose their asynchronicity? for an example of how to store the data in the service.

Resources