I am trying to show single trail information on trailDetails.html when I click this link on my searchTrails.html. And there is nothing on trailDetails.html. But if I move codes in getDataService.js to searchTrailsController.js, everything will be ok. I don't figure out why. Could anybody give some suggestions?
app.js:
var app = angular.module("crowd", ["ngRoute"]);
app.config(function ($routeProvider){
$routeProvider.when("/",{
templateUrl:"views/searchTrails.html",
controller:"searchTrailsCtrl"
});
$routeProvider.when("/trails/:trailId", {
templateUrl: "views/trailDetails.html",
controller: "searchTrailsCtrl"
});
})
getDataService.js:
app.service("dataService", function ($http, $routeParams){
this.getSingleTrail = function (){
var trail = [];
$http.get("http://localhost:8080/DMW-skeleton-1.0/trail/findTrailByTrailId/" + $routeParams.trailId)
.success(function (data){
trail.push(data);
})
return trail
}})
searchTrailsController.js:
app.controller("searchTrailsCtrl", function ($scope, dataService ) {
$scope.trail = dataService.getSingleTrail();})
But there comes nothing in trailDetails.html:
<p>{{trail.trailInfo.trailDescription}}</p>
The problem is that your data coming asynchronously but you try save them synchronously.
Step by step:
You define variable trail = []
You return trail variable to controller
Server responds with data (but you already return trail)
You can solve this problem by using next code:
app.service("dataService", function ($http, $routeParams){
this.getSingleTrail = function (){
var trail = [];
return $http.get("http://localhost:8080/DMW-skeleton-1.0/trail/findTrailByTrailId/" + $routeParams.trailId);
}})
app.controller("searchTrailsCtrl", function ($scope, dataService ) {
$scope.trail;
dataService.getSingleTrail().success(function(data){
$scope.trail = data;
});
})
Related
Login.js:
app.controller('LoginFormController', ['$scope','$http','$rootScope', '$state', function($scope, $http, $rootScope, $state) {
$scope.user = {};
$scope.authError = null;
$scope.login = function() {
$scope.authError = null;
var emailId = $scope.user.email;
var password = $scope.user.password;
$http({
url: 'http://localhost:8090/login/login',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: 'email='+emailId+'&password='+password
//data: {'email': $scope.user.email, 'password': $scope.user.password}
}).then(function(response) {
console.log(response.data);
if (response.data.status == 'SUCCESS') {
$scope.user = response.data.user.firstName;
$rootScope.test = response.data.user.firstName;
console.log("check: ",$rootScope.test)
$state.go('app.dashboard');
} else {
//alert('invalid login');
$scope.authError = 'Email or Password not right';
}
}, function(x) {
$scope.authError = 'Server Error';
})
};
}])
I saved the value under $rootScope.test
Here Is my App.main.js:
'use strict';
angular.module('app').controller('AppCtrl', ['$scope','$rootScope',
function($scope, $rootScope) {
$scope.user5 = $rootScope.test;
}
]);
trying to print the rootscope
If I run this Code i am facing the error of $rootScope is undefined in the console. How to Resolve this
$rootScope is the parent of all $scope, each $scope receives a copy of $rootScope data which you can access using $scope itself.
Here is a modified version
https://jsfiddle.net/sedhal/g08uecv5/17/
angular.module('myApp', [])
.run(function($rootScope) {
$rootScope.obj = {
"name":"user1",
"bdate":"18/11/1994",
"city":"Ahmedabad"
};
})
.controller('myCtrl', function($scope, $rootScope) {
$scope.data = $rootScope.obj;
})
.controller('myCtrl2', function($scope, $rootScope) {
$scope.data1 = $rootScope.obj;
});
There is a useful answer to your question here: https://stackoverflow.com/a/18881189/9013688
Instead of passing directly your property on the $rootScope, you could emit an event which could be listened in an other part of your app like this:
if (response.data.status == 'SUCCESS') {
$rootScope.$emit('user-logged', response.data.user.firstName)
}
And then:
$rootScope.$on('user-logged', function(event, data){
do something with your data
})
Or you could use a service which is a good way to handle your data in all your app.
Please ensure that you take the advice of georgeawg, his suggestion seems to be the best way to implement this functionality in my opinion.
I want to suggest what might be wrong with your example.
If you can see that in the main App.main.js you have given the declaration as
angular.module('app').controller(...
But you are using a variable app in login.js like so.
app.controller(...
Which I am assuming you are creating somewhere else. Thus the set rootscope value is lost because there are two instances of the same app.
The solution to your problem will be to declare one variable app which will store the instance of the app. So the fix for your solution will be to modify App.main.js to be like so.
var app = angular.module('app');
app.controller(...
Also you need to remove any other arbitary var app = in your complete code, since these will create multiple instances of the same app.
I hope my explanation was understandable and the correct guess, please try out this solution!
In your main js add this.
app.run(['$rootScope', function($rootScope) {
$rootScope.test;
}]);
Here is a sample implementation of george's suggestion which is the proper way to handle this.
app.controller('LoginFormController', ['$scope','$http','$rootScope', '$state', 'stateService', function($scope, $http, $rootScope, $state, stateService) {
var userFirstName = 'John';
stateService.setFirstName('Bill');
userFirstName = stateService.getFirstName();
console.log(userFirstName); // result will be 'Bill'
}])
And the service which I usually call stateService
app.factory('stateService', [factory]);
function factory() {
var userFirstName = null;
stateService.getFirstName = function() {
return userFirstName;
};
stateService.setFirstName = function(firstName) {
userFirstName = firstName;
};
return stateService;
}
I have a resource file that sometimes is read, and sometimes is undefined and crashes all the application. I do not know why it only works sometimes and it is causing me trouble to figure a solution out. On my controllers I am passing the service that I created to read the file which is appResourcesService:
app.controller('CommonController', ['$scope', '$location', 'appResourcesService',
function ($scope, $location, appResourcesService)
And the service to read resoruces is the following:
'use strict';
app.factory('appResourcesService', ['$resource', function ($resource) {
var appResourcesServiceFactory = {};
appResourcesServiceFactory.getResources = function ($scope, language, locale) {
var languageFilePath = 'resources/AppResources.json';
$resource(languageFilePath).get().$promise.then(function (data) {
$scope.appResources = data;
}, function (reason) {
var defaultLanguageFilePath = 'resources/AppResources.json';
$resource(defaultLanguageFilePath).get(function (data) {
$scope.appResources = data;
});
});
};
return appResourcesServiceFactory;
}]);
Like I said, sometimes it works without any kind of problem, but sometimes when in the controller I reach the piec eof code $scope.appResources, appResources is undefined. I think it is maybe because it reaches there before the file is read, but I am not being able to find a solution to avoid it.
Your factory should return a promise.
It's the job of your controller to handle data. (I use $http as it's cleaner)
app.factory('appResourcesService', ['$http', function($http) {
var appResourcesServiceFactory = {};
appResourcesServiceFactory.getResources = function () {
var languageFilePath = 'resources/AppResources.json';
return $http.get(languageFilePath).then(function(response) {
return response.data;
});
)};
return appResourcesServiceFactory;
}]);
You resolve the promise inside the controller with .then to get the data and set your scope.
appResourcesServiceFactory.getResources().then(function(data) {
$scope.appResources = data;
})
(function () {
angular.module("app").controller('DashboardController', ['$q', 'dashboardService', function ($scope, $q,dashboardService) {
var DashboardController = this;
dashboardService.loadFromServer(DashboardController );
console.log("DashboardController ", DashboardController);
}])
})();
angular.module("app").service('dashboardService', ['$http', '$q', function ($http, $q) {
return {
loadFromServer: function (controller) {
var getDashboardEntries = $http.get('http://someUrl');
var getEmailData = $http.get('http://someOtherUrl');
var getSidebarData = $http.get('http://yetAnotherUrl');
return $q.all([getDashboardEntries, getSidebarData, getEmailData])
.then(function (results) {
controller.dashboardData = results[0].data;
controller.chartData = results[1].data;
controller.emailData = results[2].data;
});
},
};
}]);
1.The service returns the three bits of data and this is the results when logged using:
console.log("DashboardController ", DashboardController);
When I try to drill down on the data in this manner it logs "undefined"
console.log("DashboardController "DashboardController.dashboardData);
console.log("DashboardController "DashboardController.chartData);
console.log("DashboardController "DashboardController.emailData);
Do you realize that console.log is executed right after invoking loadFromServer before the server has chance to respond and promise resolves? The actual order is:
loadFromServer
console.log
promise success method - where you actually have your data
Change your controller's code to this:
dashboardService.loadFromServer(DashboardController ).then(function() {
console.log("DashboardController ", DashboardController);
});
What would be even better is to construct some object from parts of responses and assign it in the controller itself - not the service. In current implementation if you wanted to have another controller then service would assign response parts to same fields. I'd propose sth like this:
return $q.all([getDashboardEntries, getSidebarData, getEmailData])
.then(function (results) {
var data = {
dashboardData = results[0].data;
chartData = results[1].data;
emailData = results[2].data;
};
return data;
});
and then in controller:
dashboardService.loadFromServer().then(function(data) {
DashboardController.dashboardData = data.dashboardData;
DashboardController.chartData = data.chartData;
DashboardController.emailData = data.emailData;
});
In this solution the controller decides what to do with data, not the other way around.
I'm trying to pass data from one controller to another using a service, however no matter what I'm trying it always returns 'undefined' on the second controller. Here is my service :
app.service('myService', ['$rootScope', '$http', function ($rootScope, $http) {
var savedData = {}
this.setData = function (data) {
savedData = data;
console.log('Data saved !', savedData);
}
this.getData = function get() {
console.log('Data used !', savedData);
return this.savedData;
}
}]);
Here is controller1 :
.controller('HomeCtrl', ['$scope','$location','$firebaseSimpleLogin','myService','$cookies','$window', function($scope,$location, $firebaseSimpleLogin, myService, $cookies, $window) {
loginObj.$login('password', {
email: username,
password: password
})
.then(function(user) {
// Success callback
console.log('Authentication successful');
myService.setData(user);
console.log('myservice:', myService.getData()); // works fine
}]);
And then controller2:
// Dashboard controller
.controller('DashboardCtrl', ['$scope','$firebaseSimpleLogin','myService',function($scope,$firebaseSimpleLogin, $location, myService) {
console.log('myservice:', myService.getData()); //returns undefined
}]);
That is simple code, unfortunately I've been struggling for a few hours now, any suggestion ? Thanks.
Created a fiddle here:
http://jsfiddle.net/frishi/8yn3nhfw/16
To isolate the problem, can you remove the dependencies from the definition for myService and see if that makes it work? Look at the console after you load the fiddle.
var app = angular.module('app', [])
.service('myService', function(){
this.getData = function(){
return "got Data";
}
})
I assume the issue is that you are returning this.savedData in the service. Try returning savedData.
this behaves different in Javascript than in other languages.
I am dynamically loading my controllers using the 'resolve' snippet in my app-config.js as shown below, which is working; but now, I want to use a $stateProvider.decorator, so I don't need to add the same snippet in every state. I can't seem to get it to work. Can someone help to point out the problem?
Here is the decorator that is not working:
$stateProvider
.decorator('data', function(state, parent) {
var stateData = parent(state);
var data = stateData.data || {};
console.log ("State Data = " + JSON.stringify(stateData));
console.log ("Data = " + JSON.stringify(data));
var controllerName = (state.name).replace("-", "/");
console.log ("Controller Name = " + JSON.stringify(controllerName));
state.resolve = state.resolve || {};
state.resolve.load = ['$q', '$rootScope', function ($q, $rootScope) {
var loadController = '/jbossews-1.0/' + controllerName+ 'Controller.js';
console.log ("loadController=" + loadController);
var deferred = $q.defer();
require([loadController], function () {
$rootScope.$apply(function () {
deferred.resolve();
});
});
return deferred.promise;
}];
return stateData;
})
Here is the snippet in my app-config.js that is WORKING without the decorator:
.state ('login', angularAMD.route({
url: '/Accounts/Login',
templateUrl: '/jbossews-1.0/Accounts/Login.html',
resolve: {
load: ['$q', '$rootScope', function ($q, $rootScope) {
var loadController = '/jbossews-1.0/Accounts/LoginController.js';
console.log ("loadController=" + loadController);
var deferred = $q.defer();
require([loadController], function () {
$rootScope.$apply(function () {
deferred.resolve();
});
});
return deferred.promise;
}]
}
}))
The stateName looks like this in index.html:
<li ng-switch-when="true" ng-click="logout()"><a ui-sref="Accounts-Logout"><span class="glyphicon glyphicon-user"></span> Logout</a></li>
Working in the example AngularFire-Seed project, I saw the following comment that potentially relates to your problem.
unfortunately, a decorator cannot be use here because they are not
applied until after the .config calls resolve, so they can't be used
during route configuration, so we have to hack it directly onto the
$routeProvider object
Please see example code from angular seed project. Even though you are using ui-router and the demo uses ngRoute, I believe the underlying premise will assist in your problem.