Unable to display angularjs page data after route change. - angularjs

I am relatively new to angularjs and seems like I am missing something obvious here. I tried to go through documentation and tutorials, but unable to find any solution to my problem.
I have a REST service at "localhost:8080/app/rest/schools/{schoolId}/selectedindicators". I can display the results in an angularjs app page (selectedindicator.html) like so:
<tbody>
<tr ng-repeat="selectedindicator in selectedindicators">
<td>{{selectedindicator.id}}</td>
<td>{{selectedindicator.school.name}}</td>
<td>{{selectedindicator.userId}}</td>
<td>{{selectedindicator.dateVisit}}</td>
<td>
<button type="submit"
ng-click="update(selectedindicator.id)"
class="btn">
<span class="glyphicon glyphicon-pencil"></span> Edit
</button>
</td>
</tr>
</tbody>
Until this point everything is working fine. But, when I try to select one of the selected indicators by clicking on the Edit button I can not display the data on the Edit (selectedindicatorForm.html) page. Here is chunk of my Edit page.
<div>
<div class="form-group">
<label>ID</label> <input type="text" class="form-control" name="id"
ng-model="selectedindicator.id" required>
</div>
.
.
.
.
.
.
</div>
Here is my routeProvider code:
myApp
.config(['$routeProvider', '$httpProvider', '$translateProvider',
function ($routeProvider, $httpProvider, $translateProvider) {
$routeProvider
.when('/selectedindicator', {
templateUrl: 'views/selectedindicators.html',
controller: 'SelectedIndicatorController',
resolve:{
resolvedSelectedIndicator: ['SelectedIndicator', function (SelectedIndicator) {
return SelectedIndicator.query();
}]
}
})
.when('/selectedindicatorForm',{
templateUrl: 'views/selectedindicatorForm.html',
controller: 'SelectedIndicatorFormController',
})
}]);
Here is my controller code for the update method:
myApp.controller('SelectedIndicatorController', ['$scope', '$location', '$route','resolvedSelectedIndicator', 'SelectedIndicator',
function ($scope, $location,$route, resolvedSelectedIndicator, SelectedIndicator) {
$scope.selectedindicators = resolvedSelectedIndicator;
$scope.update = function (id) {
$scope.selectedindicator = SelectedIndicator.get({id: id});
$location.path("/selectedindicatorForm");
};
}]);

you can add a separate service (singleton object) to pass data between controllers .
looks like you SelectedIndicator (which is passed onto SelectedIndicatorController) is already doing that and you can simply re-use it .
On your SelectedIndicatorFormController inject this service SelectedIndicator and call SelectedIndicator.get({id: id});
Note - looks like this line $scope.selectedindicator = SelectedIndicator.get({id: id}); inside SelectedIndicatorController doesn't serve any purpose.
If you could setup a plunk, I could help you.

Is there some reason you're transitioning using $location.path?
The way I'd do that would be just put an or something, with a class="btn" or some other css styling if you really want it to look like a button. With regular ngRoute, you just work with URLs, and should put all the state into the URL. I'm pretty sure setting a $scope variable and then manually changing the state doesn't actually do anything, since the new state has its own $scope.
To be perfectly frank after looking at that code, I'm going to say that you probably ought to read some angular tutorial stuff. I found egghead.io to be pretty great myself.

Related

Loading ng-view html templates

I have one index.html page and I am using ng-view. The two HTML templates are page1 and page2.
I have a button to which I have attached an ng-click function. When the function is fired, I am fetching weather data using $resource and also using the weather url inside amcharts dataloader to make a graph from weather information.
Now, if I do not separate the templates and keep everything on one page, everything works fine. But when I separate them and take the input from the index.html page, nothing works. I guess because when page1 and page2 are loaded, the information fetched by the function is lost.
Is there an elegant way to do this? Ideally I want my index.html to take input from the user. Like, "enter city" and I want that when I load /page1 there should be the weather data and on page2, the weather chart, without again asking for input from the user.
Right now I am taking the input in page1 but ideally I would like it to be in main index.html.
I am sure that the code is correct and I am correctly using routing and this is more of an error that has to do with the logic and priority of execution.
I am still quite new to angularjs. So please :)
JavaScript
$app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'page1.html',
controller: 'weatherController'
})
.when('/graph', {
templateUrl: 'page2.html',
controller: 'weatherController'
})
.otherwise({
redirectTo: '/'
})
});
app.controller('weatherController', ['$scope', '$resource', '$routeParams', function($scope, $resource, $routeParams) {
$scope.GetWeatherInfo = function() {
// getting weather data for page1.html
// getting chart data for page2.html
...
}
}]);
HTML (Page1.html)
<div ng-controller="weatherController">
<input type="text" name="city" id="city" class="form-control" placeholder="Stadt" ng-model="city_name" />
<button id="submitWeather" class="btn btn-primary" ng-click="GetWeatherInfo()"> zum Wetter </button>
Temperature: Min: {{w.main.temp_min}}
Max: {{w.main.temp_max}}
HTML (Page2.html)
<div ng-controller="weatherController">
<div id="chartdiv"></div>

AngularJs :: Share data between Views and parameters

I'm creating an App with Ionic Framwork.
The Front is ok, and I made the view transitions using $stateProvider.
But I need to do the APP features and other functionalities. I have 2 major problems
1) Pass parameters through href=""
2) Execute some functions after the view transition e when the data is processed show the info on the new View.
Couldn't go further because I'm newbie at Angular and the other examples I searched were not specific.
That's what I got so far::
INDEX.HTML
<body ng-controller="AppController as controller">
<ion-view title="View1"><ion-content>
<a href="#/view2" ng-click="controller.test1">
<button class="button-style">TEST 1</button>
</a>
<a href="#/view2" ng-click="controller.test2">
<button class="button-style">TEST 2</button>
</a>
</ion-content></ion-view>
...
View2.HTML
<ion-view title="View2"><ion-content>
<input type="text" value="{{controller.parameter}}" />
</ion-content></ion-view>
APP.JS
app.config( function($stateProvider, $urlRouterProvider){
$stateProvider
.state('view2',{
url:'/view2',
templateUrl:'views/view2.html'
})
...
app.controller('AppController', ['$scope', function($scope){
parameter = '';
this.test1 = function(){
alert('test1');
parameter = 'One';
};
this.test2 = function(){
alert('test2');
parameter = 'Two';
};
}]);
I've tried alot. But now it's just guessing :(
I didn't understand how Controllers and $scope works. I've saw some examples using factory and service, even the CodeSchool (awesome by the way) coudn't help me...
So, any good soul can bring some light here?
Sorry about my misspelled english
First of all, you should be using the ui-sref attribute in your <a> tags (since you're using states, although using href works too), like this:
<a ui-sref="view2"></a>
And if you want to pass parameters, you have to configure your state's url to accept parameters:
url: '/view2/:parameter'
To access parameter in your controller, you'll also need to inject $stateParams into your controller:
app.controller('AppController', function($scope, $stateParams) {
});
And you access parameter via $stateParams.parameter like this:
app.controller('AppController', function($scope, $stateParams) {
alert($stateParams.parameter);
$scope.parameter = $stateParams.parameter;
});

How to prevent losing data when moving from one state to another in multi-step form?

I am new to web programming and especially to AngularJS.
So maybe my question will seem naive to some of you.
I'm developing a single page application using angular-ui-router.
I have created a multi-step form that contains 3 states:
(function () {
"use strict";
angular.module("sensorManagement", ["ui.router", "ngAnimate", "ngResource", "toaster"])
.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterPorvider) {
$urlRouterPorvider.otherwise("/Sensor/Home");
$stateProvider
.state("MultiStepForm", {
url: "/Sensor/MuiltyStepForm",
templateUrl: "/app/MultiStepForm/MuiltyStepForm.html",
})
.state('MultiStepForm.step1', {
url: '/step1',
templateUrl: '/app/MultiStepForm/FormStep1.html'
})
.state('MultiStepForm.step2', {
url: '/step2',
templateUrl: '/app/MultiStepForm/FormStep2.html'
})
.state('MultiStepForm.step3', {
url: '/step3',
templateUrl: '/app/MultiStepForm/FormStep3.html'
});
}]);
})();
Here is the HTML code:
<!-- form.html -->
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div id="form-multiple-step">
<div class="page-header text-center">
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref=".step1"><span>STEP1</span></a>
<a ui-sref-active="active" ui-sref=".step2"><span>STEP2</span></a>
<a ui-sref-active="active" ui-sref=".step3"><span>STEP3</span></a>
</div>
</div>
<form id="single-form">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
</div>
</div>
As you can see I have 3 states and each state has it's own view. The views have multiple elements (textboxes and checkboxes).
When the user enters some data for the STEP1 view and moves to the next step (STEP2 or STEP3) then at some point goes back to STEP1 all data is deleted. I checked with fiddler and can see that when I move from one state to another a call is made to the server and a new view generated.
My question is how can I prevent the lose of data when I move from one state to another? Do I have to use caching? Or maybe there is another way to prevent server calls and keep the data alive until the submit button clicked.
When you feel you have to save data across your controllers in your app. you should use a service.
app.factory('sharedDataService', function ($rootScope) {
console.log('sharedDataService service loaded.');
// do something here that can be shared in other controller
});
//pass this service in your controller to use it there
app.controller('Controller2', ['$scope', 'sharedDataService', function ($scope, sharedData) {
console.log('Controller2 controller loaded.');
//get data from shared service
}]);
find a useful Fiddle here
Cheers if it helps!
I think what you need to do is share you $scope between the parent and child stats. here is the stackoverflow post with good example. https://stackoverflow.com/a/27699798/284225

Angular Links in view not working

I am just beginning to experiment with AngularJS and have come across a problem.
My main page renders a <ng-view> element and I have set up the following routes:
(function () {
var routes = function ($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'Home/Overview',
controller: 'OverviewPageController'
})
.when('/Issue/:id', {
templateUrl: 'Home/Issue'
})
.otherwise({ redirectTo: '/' });
}
routes.$inject = ['$routeProvider'];
angular.module('PublicationSchedulerApp')
.config(routes);
}());
If I add a link tag outside of the <ng-view>:
<a ng-href="#/Issue/123">Issue</a>
The 'Issue' page is loaded into the view as expected.
In my case however, the Overview controller loads some data via an asynchronous Ajax call and then renders a table with a custom directive which, in turn, uses <ng-repeat>. If I create the same link within this directive/table:
<tr ng-repeat="issue in issues">
<td>
<a ng-href="#/issue/{{ issue.issueId }}">{{ issue.subject }}</a>
</td>
</tr>
The routing doesn't work. As you can see, I have played around with changing the link attribute from href to ng-href but this doesn't seem to make any difference. I am guessing that the asynchronous loading of the data is somehow breaking the routing, but I am not sure how to fix it. A couple of posts suggested that I reload the $route after the data load:
angular.module('PublicationSchedulerApp')
.run(['$route', function ($route) {
$route.reload();
}]);
but this didn't appear to make any difference either.
Any help would be much appreciated - thanks.
In Angular, routes are case sensitive. So make sure that your links match your route.
<tr ng-repeat="issue in issues">
<td>
<a ng-href="#/Issue/{{ issue.issueId }}">{{ issue.subject }}</a>
</td>
</tr>
You can also use ui-router, that way you will be able to create your links with state names rather than URLs (easier to maintain and less error-prone).

Angular-UI Bootstrap toggle buttons in AngularJS

I originally had the default Bootstrap 3.3 toggle buttons in my app. These are the grouping of buttons that mimic the behavior of checkboxes or radio buttons.
I was trying to replace them with the ones here
I paste the code into my html, and at first it looks fine:
<div class="btn-group">
<label class="btn btn-default" ng-model="checkModel.left" btn-checkbox>Left</label>
<label class="btn btn-default" ng-model="checkModel.middle" btn-checkbox>Middle</label>
<label class="btn btn-default" ng-model="checkModel.right" btn-checkbox>Right</label>
</div>
Now I want to hook up the controller. So, I create a file "elements-buttons.controller.js" with the contents of the JS from the angular-ui site:
(function() {
'use strict';
angular.module('pb.ds.elements').controller('ButtonsController',
function($log) {
var _this = this;
_this.singleModel = 1;
_this.radioModel = 'Middle';
_this.checkModel = {
left: false,
middle: true,
right: false
};
});
})();
I put the controller into my router:
.state('elements.buttons', {
url: '/elements/buttons',
templateUrl: 'modules/elements/templates/elements-buttons.html',
controller: 'ButtonsController as buttons'
})
Now, as soon as I link the controller to my index.html, the button group loses all styling:
Which makes no sense to me at all. Inspecting the code in Chrome shows it's if fact lost all its classes for some reason:
<div class="btn-group">
<label class="" ng-model="buttons.checkModel.left" btn-checkbox="">Left</label>
<label class="" ng-model="buttons.checkModel.middle" btn-checkbox="">Middle</label>
<label class="" ng-model="buttons.checkModel.right" btn-checkbox="">Right</label>
</div>
Now, since I have used "controller as" syntax, I did make sure to try adding that to the model ng-model="buttons.checkModel.right" but with or without this same thing. No controller, looks fine. Controller, boom.
EDIT/UPDATE: There are no errors in the console of any kind.
I have created a jsfiddle in order to debug your problem.
Check it here.
And Im finding no problems on it.
Key points you should check:
Be sure you are adding all neccessaries files, such as ui-bootstrap.js
ui-bootstrap.css
jquery, since this are just directives for angular, it will also need jQuery (as the original bootstrap does)
include the dependency on ui-bootstrap on you app definition, pay attention to this line -> angular.module('app', ['ui.bootstrap', 'app.controllers']);
ng-app & ng-controller on the markup. Be sure you are not forgetting this
On the fiddle, Im not using ui-router, but you should check that the controller is indeed loading (you can add a console.log there and check that the controller is loaded).
I thing with this guidelines and the jsfiddle, you should be good to go

Resources