Getting value from a firebase object using angularJS in a controller - javascript

I am trying to access user data in a controller via a service. The service returns the object correctly
{
"$id": "9ecadf8e-a233-48ac-bebf-26b50ea2855d",
"$priority": null,
"branch": "London",
"email": "manager#london.co.uk",
"firstName": "John",
"lastLogin": 1467975594697,
"lastLoginPrevious": 1467975348837,
"lastName": "Smith",
"role": "Manager"
}
when accessing the data from the controller I can access the $id successfully by using
$scope.userData = UserService.getUserData();
console.log($scope.userData.$id)
but when trying to access any other node such as role
$scope.userData = UserService.getUserData();
console.log($scope.userData.role)
I just get 'undefined' in the console. Obviously I am not doing this correctly but stuck on what I should try next.
Here is my service that retrieves the data from firebase
.service('UserService', ['$location', '$firebaseAuth','$firebaseObject', function ($location, $firebaseAuth, $firebaseObject) {
var userData = '';
var ref = new Firebase("https://firebase-url");
var authData = ref.getAuth();
var userUID = authData.uid;
var userRef = new Firebase("https://firebase-url/Users/" + userUID);
var userData1 = $firebaseObject(userRef);
return {
getUserData: function () {
if (userData == '') {
userData = userData1;
}
return userData;
},
};

You could possibly be having an asynchronous issue. Here is an example of my code in a controller (Firebase 3.0):
// Gets reference to resources tree, SERVICE CALL
$scope.resourceNames = submissions.getResourceNames();
// Could be previously loaded, check
if(Object.keys($scope.resourceNames).length === 0 && $scope.resourceNames.constructor === Object) {
// Get reference
var resourceNameRef = firebase.database().ref("/resourceNames");
firebase.database().goOnline();
// Return JSON object of data at specified location
$scope.resourceNames = $firebaseObject(resourceNameRef);
// When resources loaded
$scope.resourceNames.$loaded().then(function(data) {
// Store into service, SERVICE CALL
submissions.setResourceNames(data);
// DO WHATEVER
}).catch(function(error) {
console.error("Error:", error);
});
} else {
// WAS ALREADY LOADED
}
What I have done is check the service to see if the data has already been loaded (by another controller) and if it wasn't I call the data, wait for it to be loaded and then store it inside my service.
I can then use the data as I please inside the controller or in the view:
<p>
{{resourceNames.$id}}
</p>
<p>
{{resourceNames.name}}
</p>
<!-- etc -->

Related

How to receive error while inserting in store?

I am using angular-indexedDB for indexedDB in AngularJS.
I want to receive error if insert is not successful. But I am not getting any error it just comes out of the function if I run the same code twice as I have made name unique.
Error:
ConstraintError return _this.store.add(item);
ConstraintError req =
this.store.openCursor();
Code:
angular.module('myModuleName')
.controller('myControllerName', function($scope, $indexedDB) {
$scope.objects = [];
$indexedDB.openStore('people', function(store){
store.insert({"ssn": "444-444-222-111","name": "John Doe", "age": 57}).then(function(e){console.log('inside insert');});
store.getAll().then(function(people) {
// Update scope
$scope.objects = people;
});
});
});
I think adding error callback inside promise .then should work
Also do create a getAll method to retrieve all data from objects, in that do response.data to get data returned from server.
Code
angular.module('myModuleName')
.controller('myControllerName', function($scope, $indexedDB) {
$scope.objects = [];
$scope.getAll = function(){
store.getAll().then(function(response) {
// Update scope
$scope.objects = response.data;
});
};
$indexedDB.openStore('people', function(store){
store.insert({"ssn": "444-444-222-111","name": "John Doe", "age": 57})
.then(function(e){
console.log('inside insert');
//reload data only call get succeed
$scope.getAll();
}, function(error){
//do error handling stuff here
//you will get error returned from server here.
console.log('Error here', error)
});
});
});

Properly retrieve username and useful values (site title, copyright, etc.)

I have a simple web app based on this project ( https://github.com/arthurkao/angular-drywall ), running with NodeJS and AngularJS as the front-end.
I'm trying to set up a simple page that displays a list of all connected users on a map (using Google Maps, Geolocation and PubNub).
Here's how I'm actually doing it:
angular.module('base').controller('TravelCtrl',
function($rootScope, $scope, NgMap, security, $geolocation, PubNub){
$rootScope.extusers = []; //remote users
$scope.initTravel = function() { //declare the init function
PubNub.init({
subscribe_key: $rootScope.security.keys.psk,
publish_key: $rootScope.security.keys.ppk,
uuid: $rootScope.security.currentUser.username,
ssl: true
});
PubNub.ngSubscribe({
channel: "travel",
state: {
position: {},
}
});
console.log("Loaded Travel");
$geolocation.getCurrentPosition({
timeout: 60000
}).then(function(position) { //when location is retreived
$scope.position = position;
PubNub.ngSubscribe({
channel: "travel",
state: {
position: {
lat: Math.floor($scope.position.coords.latitude*1000)/1000, //decrease accuracy
long: Math.floor($scope.position.coords.longitude*1000)/1000,
},
}
});
$rootScope.$on(PubNub.ngPrsEv("travel"), function(event, payload) {
$scope.$apply(function() {
$scope.extusers = PubNub.ngPresenceData("travel");
});
});
PubNub.ngHereNow({ channel: "travel" });
$scope.showInfo = function(evt, marker) { //show user window on map
$scope.extuser = marker;
$scope.showInfoWindow('infoWindow');
};
});
};
if ($rootScope.hasLoaded()) { //if username and keys are already loaded, then init module
$scope.initTravel();
} else { //else, wait for username and keys to be loaded
$rootScope.$on('info-loaded', function(event, args) {
$scope.initTravel();
});
}
}
);
Although it works, it seems like it's very buggy and only loads sometimes. Occasionally, I get this:
Result screenshot
I really don't know what I'm doing wrong, as I simply followed the tutorials on PubNub's AngularJS SDK.
I think this has to do with how I'm initialising the application.
angular.module('app').run(['$location', '$rootScope', 'security', function($location, $rootScope, security) {
// Get the current user when the application starts
// (in case they are still logged in from a previous session)
$rootScope.hasLoaded = function() {
return (security.keys && security.info && security.currentUser); //check if everything is loaded correctly
};
$rootScope.checkLoading = function() {
if ($rootScope.hasLoaded()) {
$rootScope.$broadcast('info-loaded'); //broadcast event to "TravelCtrl" in order to init the module
}
};
security.requestKeys().then($rootScope.checkLoading); //request secret keys
security.requestSiteInfo().then($rootScope.checkLoading); //then templating info (site title, copyright, etc.)
security.requestCurrentUser().then($rootScope.checkLoading); //and finally, current user (name, id, etc.)
$rootScope.security = security;
// add a listener to $routeChangeSuccess
$rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
$rootScope.title = current.$$route && current.$$route.title? current.$$route.title: 'Default title';
});
}]);
1- Request secret keys, site info and current user with JSON API.
2- Wait until everything's loaded then init the application with the appropriate keys (PubNub, Google Maps)
--
My question is:
How do you instantiate an AngularJS app after retrieving useful information via a RESTful API?
I'm pretty new to AngularJS, and I wouldn't be surprised if my approach is totally ridiculous, but I really need to get some advice on this.
Thanks in advance for your help,
Ulysse
You don't have to wait that the AJAX Query ended to initate the angular APPs.
you can use the $http promise ( details her )
In the controller :
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
// data is now accessible in the html
$scope.data = response ;
// you can call a function to add markers on your maps with the received data
addMarkerOnMap(response);
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
You can also add a watch on some variable to wait modification on them :
// you should have $scope.yourVarName declared.
$scope.$watch('yourVarName', function(newValue, oldValue) {
console.log(newValue);
});
Or watch a list/object
$scope.$watchCollection('[var1,var2]', function () {
},true);

Can't Persist New User to Firebase Database

I've been reading countless tutorials and I'm not able to get any data to appear in the firebase database at all. I'm trying to get this structure
"my-app-name": {
"users": {
"uid-of-user": {
"email": "them#them.com",
"todoitems": {
}
}
}
}
First of all I'm not sure how to acquire that structure. Under "my-app-name" in the visual editor, I've put "users" = "". I'm not sure if that's the way to star establishing users as an empty object. Or maybe I shouldn't be dealing with the visual editor at all? Here's my createNewUser controller that should be persisting new users to the database:
function LoginController($scope, Auth, $state, $location, $firebaseObject, $firebase) {
$scope.createNewUser = createNewUser;
$scope.signupComplete = "";
function createNewUser() {
var ref = new Firebase("https://sizzling-torch-655.firebaseio.com/");
//CREATE USER
Auth.$createUser({
email: $scope.email,
password: $scope.password
}).then(function(userData) {
//THIS SHOULD BE PERSISTING IT TO THE DATABASE
var user = $firebaseObject(ref.child('users').child(userData.uid));
user.$loaded().then(function() {
var newUser = {
emailAddress: $scope.email,
};
user.$ref.$set(newUser);
})
// $location.path("/home");
}).catch(function(error) {
$scope.responseMessage = error;
});
};
};
It should be noted I haven't created the users object yet in the firebase database. Any help is extremely appreciated. Thank you very much.
Clarification
Auth.$creatUser is:
app.factory("Auth", ["$firebaseAuth", function($firebaseAuth) {
return $firebaseAuth(ref);
}]);
I've successfully created users and see them appear in the Login/Users tab of the Firebase dashboard. I'm not able to store them into the database though.
And userData.uid is the userData object that was returned from the then part of the $createUser function.
EDIT 2
These are my security and rules. Could this be affecting me writing user data to the database?
This is going to be a todo app. Users should be able to only have access to their own data.
{
"rules": {
// public read access
".read": true,
"users": {
"$uid": {
".write": "$uid === auth.uid"
}
}
}
}
Firebase Authentication does not automatically store user information in the database. If you want to store such information in the database, you will have to write the necessary code for that yourself.
From your snippet:
//THIS SHOULD BE PERSISTING IT TO THE DATABASE
var user = $firebaseObject(ref.child('users').child(userData.uid));
This code does not store any information in the database either. Instead it tries to read the user's data from the database. But since you didn't write it there in the first place, the read will accomplish nothing and the then() will never execute.
The solution is to write the necessary user data into the database, when the user authenticates.
var user = $firebaseObject(ref.child('users').child(userData.uid));
var newUser = {
emailAddress: $scope.email,
};
user.$ref.$set(newUser);

Didn't get json array in App js file

My service code look like belowed :-
data.service('SmartLearnerService', function ($http) {
//Get Single Records
this.get = function (id) {
return $http.get("/api/Category/");
}
});
Here is my controller code for App.js:-
$scope.questionlist = SmartLearnerService.get();
$scope.questionlist.then(function (pl) {
var res = pl.data;
$scope.que = res.QuestionLabel;
},
function (errorPl) {
console.log('failure loading Employee', errorPl);
});
console.log($scope.questionlist);
Here is Controller code for web api controller :-
public class CategoryController : ApiController
{
CommonDb db = new CommonDb();
public JsonResult Get()
{
var Result = db.GetQuestionById().ToList();
string message = "No Data Found";
if (Result.Count() != 0)
{
return new System.Web.Mvc.JsonResult()
{
Data = Result,
JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet
};
}
else
{
return new System.Web.Mvc.JsonResult()
{
Data = message,
JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet
};
}
}
}
}
And here is div tag where i want to bind questions from json result using ng-repeat directive.
<div class="question" align="center">{{Questions.QuestionLabel}}</div>
i am facing problem while binding json array in controller's $scope.questionlist and i am successfully getting json result from web api controller.
Ok, if I had to guess (and that's exactly what I'm doing), you want something like this in your controller...
SmartLearnerService.get().success(function(questions) {
$scope.questionList = questions;
});
or, if you're not a fan of the add-on success / error callbacks
SmartLearnerService.get().then(function(response) {
$scope.questionList = response.data;
});
and in your template
<div ng-repeat="question in questionList">
<div class="question" align="center">{{question.QuestionLabel}}</div>
<!-- and so on -->
</div>
This is totally assuming your C# controller returns JSON that looks something like...
[{
"QuestionID": "1",
"QuestionLabel": "Why are mirrors often slightly curved (convex) ?",
"Image": "zibra-crossing.jpg",
"Correct": "two",
"Explaination": "Question one explaination is goes here"
}, {
...
}]
Can you try this?
SmartLearnerService
.get()
.success(function (data, status) {
if (status === 200) {
//your code to process data is here
}else{alert(status)}
})
.error(function (data, status) {
//TODO: Use nice alert.
alert('Server request failed with status ' + status + ' while getting area in the ' + $item.Name);
});
You will get the status code that you are receiving and then you can change the code accordingly.
The approach that I took in my case was to serialize using JsonConvert from NewtonSoft and then return the string of Json object instead of Json object itself to improve the speed.

sessionStorage data not persist in AngularJS app with ngStorage

All,
I'm simply trying to store a user object in sessionStorage in an AngularJS app. If I step through this in either the Chrome or FF debugger, the sessionStorage never gets set. Here is my angular service code:
// Authentication/authorization Module
stonewall.authModule = angular.module("authModule", [
// Module dependencies
"ngStorage"
]);
// Authentication/authorization service tracks the current user
stonewall.authModule.service('authService', function ($localStorage, $sessionStorage) {
// Initialize current user
var currentUser = {};
restoreSession();
// Declare storage type-this may change if user selects
// "Keep me signed in"
var storageType = {};
// Return the current user object
this.getCurrentUser = function () {
return currentUser;
};
// Returns whether there is a currently authorized user
this.userAuth = function() {
return currentUser.sid != "";
};
// Logout function, initializes the user object
this.logout = function() {
currentUser = {
sid: "",
status: 0,
pswLastSet: 0,
id: "",
sigUID: "",
sig: ""
};
//persistSession();
};
// Login
this.login = function(user, subj) {
if (user == null) return;
currentUser = {
sid: user.Principal.SId,
status: user.Principal.ControlStatus,
pswLastSet: new Date(user.Principal.PasswordLastSet),
id: user.Identity.Id.DN,
sigUID: user.Identity.Certificates[0].UID,
sig: stonewall.hash(user.Principal.SId + subj.pswd),
};
persistSession();
};
// Persist to session storage
function persistSession() {
$sessionStorage.currentUser = currentUser;
};
// Restore session
function restoreSession() {
currentUser = $sessionStorage.currentUser;
if (currentUser == null) {
// Initialize to empty user
currentUser = {
sid: "",
status: 0,
pswLastSet: 0,
id: "",
sigUID: "",
sig: ""
};
}
};
});
And, here is a screencap that shows my FF debugging session. You can see that after persistSession is called that $sessionStorage has my user.
But, if I switch over to the DOM inspector, sessionStorage has no items in it...
Any help is, as always, appreciated.
Are you sure you are using angular's sessionStorage in the right way?
Session storage is a property of the $window object in angular, so I don't know if you have made your own service wrapper or something like that?
Anyway, here is a codepen that shows another approach that I use myself, using $window.sessionStorage instead: http://codepen.io/chrisenytc/pen/gyGcx

Categories