Angular + Breeze get entity from metadata without fetching results - angularjs

Hi there i want to create a form based on the metadata retrieved from breeze to leverage the validation. However, I can't manage to find a way to get specific entity from the Metadata without loading the result.
Is it possible to load 1 entity from metadata and bind it to a view?
I tried using the var entityMetaData = manager.metadataStore.getEntityType(“Order”); but this throws the following exception Heading
Breeze: Unable to locate a 'Type' by the name: 'Order'. Be sure to execute a query or call fetchMetadata first
so i tried to get the entity from the rawMetadata using by fetching it. But this doesn't seem to work as rawmetadata does not have getEntityType function.
(function() {
'use strict';
var controllerId = 'login';
angular.module('app').controller(controllerId, ['$location', 'authcontext','breeze', login]);
function login($location, authcontext, breeze) {
var vm = this;
var manager = null;
var entityTypeName = "Order";
breeze.NamingConvention.camelCase.setAsDefault();
manager = new breeze.EntityManager('http://localhost:54078/breeze/breeze');
manager.metadataStore.fetchMetadata('http://localhost:54078/breeze/breeze').then(function (rawMetadata) {
vm.orderModels = rawMetadata.getEntityType(entityTypeName); //,-- this does not work..
});
}
})();
What could i be doing wrong here?

The metadataStore has the metadata after the MetadataStore.fetchMetadata promise returns. i.e.
manager.metadataStore.fetchMetadata('http://localhost:54078/breeze/breeze').then(function () {
vm.orderModels = manager.metadataStore.getEntityType(entityTypeName);
});

Related

Sending data from Angular 1.x Factory to Angular 1.x controller

I have a service defined which do the db related queries/updates. I have defined the controller which does the data parsing for the angular elements by getting the objects from the service. I would like to keep each scope different
How can I pass the data from service to controller using ngResource.
Sample Service:
app.factory("ioHomeService", ["$rootScope","$resource", function($rootScope,$resource) {
var svc = {};
var home = $resource('/home/getAll');
var dbData= home.get();
svc.getRooms = function() {
return dbData;
};
return svc;
}]);
Sample Controller:
app.controller("homeCtrl",["$scope","$mdDialog","ioHomeService",function($scope,$mdDialog,ioHome){
$scope.dbData = ioHome.getRooms();
//Here UI specific objects/data is derived from dbData
}]);
After the DB is queried and the results are avialble the dbData in service is reflecting the data from DB, but the Controller cannot get that data
It is important to realize that invoking a $resource object method
immediately returns an empty reference (object or array depending on
isArray). Once the data is returned from the server the existing
reference is populated with the actual data. This is a useful trick
since usually the resource is assigned to a model which is then
rendered by the view. Having an empty object results in no rendering,
once the data arrives from the server then the object is populated
with the data and the view automatically re-renders itself showing the
new data. This means that in most cases one never has to write a
callback function for the action methods.
From https://docs.angularjs.org/api/ngResource/service/$resource
Since the 'ioHome.getRooms();' is being called before the $resource has returned the data you are getting dbData as an empty reference
app.factory("ioHomeService", ["$rootScope","$resource", function($rootScope,$resource) {
var svc = {
dbData : {}
};
var home = $resource('/home/getAll');
var svc.dbData.rooms = home.get();
return svc;
}]);
Controller
app.controller("homeCtrl",["$scope","$mdDialog","ioHomeService",function($scope,$mdDialog,ioHome){
$scope.dbData = ioHome.dbData;
//You can access the rooms data using $scope.dbData.roooms
//Here UI specific objects/data is derived from dbData
}]);
You would have to return the service object , like so :
app.factory("ioHomeService", ["$rootScope","$resource", function($rootScope,$resource) {
var svc = {};
var home = $resource('/home/getAll');
var dbData= home.get();
svc.getRooms = function() {
return dbData;
};
return svc; //here
}]);
Currently the getRooms method is not visible to your controller.

angular display model on view after getting data from firebase

I am working on displaying collection that I got from DB in angular with firebase DB. I have those controller and service setup. in the html, I use search.users expecting it will hold all the data that I got from the DB but it won't show up. I can't figure out why. I tried few things like angular.copy or $broadcast with no luck. Can anyone help advise on this? Appreciated in advance.
.controller('SearchController', function ($scope, SearchService, logout, $location){
var search = this;
search.users = SearchService.users;
//$scope.$on('evtputUsers', function () {
// search.users = SearchService.users;
//});
})
//service for SearchService
.factory('SearchService', function ($http, $rootScope){
var userRef = new Firebase("app url");
var broadcastUsers = function () {
$rootScope.$broadcast('evtputUsers');
};
//get the user info
//insert the data to the db.
//retrieving the data
var dbUsers;
userRef.child('users').on('value', function(snapshot){
dbUsers = snapshot.val();
// angular.copy(snapshot.val(), dbUsers);
console.log('usersinDB:',dbUsers);
broadcastUsers();
}, function(err){
console.error('an error occured>>>', err);
});
return {
users: dbUsers
};
})
Rather than using $broadcast() and $on() you should use the AngularFire module.
AngularFire provides you with a set of bindings to synchronizing data in Angular.
angular.module('app', ['firebase']) // 1
.controller('SearchCtrl', SearchCtrl);
function SearchCtrl($scope, $firebaseArray) {
var userRef = new Firebase("app url")
$scope.users = $firebaseArray(userRef); // 2
console.log($scope.users.length); // 3
}
There are three important things to take note of:
You need to include AngularFire as firebase in the dependency array.
The $firebaseArray() function will automagically synchronize your user ref data into an array. When the array is updated remotely it will trigger the $digest() loop for you and keep the page refreshed.
This array is asynchronous. It won't log anything until data has populated it. So if you're logs don't show anything initially, this is because the data is still downloading over the network.

Adding Firebase Data to Angular Service?

I am trying to inject my Firebase Object to a service so I can use different Angular Controllers to access copies of the Firebase Object.
In a previous working copy of my app. I only loaded Firebase into a controller:
Example Below:
ToDo.controller('todoController',["$scope","$firebaseArray", function($scope, $firebaseArray, ToDoData){ // injecting AngularFire & ToDoData Service
var myData = new Firebase("https:firebase url goes here"); //create Firebase obj
$scope.todos = $firebaseArray(myData); //Reading Database and adding to todos variable
$scope.historytodos = [{'title': "Old Task", 'done':true, 'timetag':new Date().toString()}];
$scope.addTodo = function(){
var datecreated = new Date().toString();
$scope.todos.$add({'title':$scope.newtodo,'done':false, 'timetag': datecreated}); //push to Array
$scope.newtodo = '';
};
Now I am trying to recreate the Firebase Dependency , but to work with a service. Here is what I have for my attempted Service.
It is erroring this
Uncaught ReferenceError: Todo is not defined
Example of my Erroneous service :
Todo.value('fbURL', "https:firebase") //Firebase URL value service
.service('fbRef',function(fbURL){ //Firebase Data Reference Service
return new Firebase(fbURL);
})
.service('fbArr',function(fbRef){ //Firebase Array service
$scope.todos = $firebaseArray(fbRef);
return $scope.todos;
});
Not sure what's causing the error & also not too sure how to create a service to hold my Firebase object.
First of all the error is self explanatory, Todo is not defined. You have to do something like:
var Todo = {fbRef: "https:firebase"};
And for the service i suggest you read up on services and factory's to see what applies best for your particular case and here is a simple example of how to do it in a service:
.service('fb', function(){
var connection = new Firebase(url);
var todos = $firebaseArray(connection);
this.url = function() { return connection;};
this.todos = function() { return todos;};
});

firebase snapshot will not return value

Another Question here,
I am using firebase and angular js, and trying to return data from my database to the console log using this code :
function userCtrl($scope){
$scope.userName="";
$scope.myData = new Firebase ("https://yjyc-signup.firebaseio.com/Entries");
$scope.users={};
$scope.saveUser = function(){
$scope.myData.push({userName: $scope.userName});
$scope.userName="RESET";
};
$scope.myData.on('value', function(snapshot) {
$scope.users = snapshot.val();
console.log("Author: " + $scope.users.name);
});
but the console return "Author: Undefined" although I have a value in my database of a name.
is anybody can help me that would be amazing
When using AngularFire you need to sync the reference before you can get any data from it. Also you're trying to use a Firebase function that doesn't exist for AngularFire as far as I'm aware. Instead try to register a $watch function in your controller and each time that $watch executes you grab the information from the reference. Something like this:
myApp.controller('UserCtrl', ['$scope', function($scope) {
$scope.$watch('watchedExpression', function() {
var ref = new Firebase ("https://yjyc-signup.firebaseio.com/Entries");
var syncedRef = $firebase(ref);
console.log('Author:' + syncedRef.name); //You need to change this path to work with your Firebase tree structure
});
}]);
If you don't want to register a $watch function you can look at the threeway data-binding, you can look at this here in the AngularFire documentation.

Firebase's AngularFire in an AngularJS service

The best way of handling Firebase in AngularJS surely has to be from within a service, so it's available to all Controllers across the App.
I just can't get it to work! ... I first tried using angularFire(new Firebase(url)), hoping I could bind to the service's scope, but Angular complains that it cannot $watch it.
So I tried angularFireCollection instead like this:
app.factory('myService', function myService(angularFireCollection) {
var url = 'https://myfirebase.firebaseio.com';
return {
getAll: function(path) {
var ref = angularFireCollection(new Firebase(url + '/' + path));
console.log(ref);
return ref;
},
...
};
});
However, the angularFireCollection is an Object containing a load of methods etc. if I bind it to a controller $scope I just get garbage. It also complains that it can't call the Firebase functions before I try to use them (e.g. Error: Firebase.push failed: second argument must be a valid function.)... anyone got any ideas where I'm going wrong?
See this PLUNKER
If you want to encapsulate some of the functionality into a service, consider keeping the returned ref in state of the service. I expanded on your plunker. It seems to mostly do what you were trying for.
http://plnkr.co/edit/Uf2fB0
Jeff answered the question correctly ... I'm just posting a further development on Jeff's example for those who are interested.
I have abstracted the Firebase service creation, so you can dynamically create an instance of whatever Firebase service you want:-
var registerFirebaseService = function (serviceName) {
app.factory(serviceName, function (angularFire) {
var _url = null;
var _ref = null;
return {
init: function (url) {
_url = url;
_ref = new Firebase(_url);
},
setToScope: function (scope, localScopeVarName) {
angularFire(_ref, scope, localScopeVarName);
}
};
});
};
You first create an instance of the service as follows
registerFirebaseService('itemsService'); // create itemsService instance
Then you can inject the itemsService service into your controllers. The instance is initialised using your Firebase URL e.g.
itemsService.init('https://firebase.firebaseio.com/' + userId + '/items');
The Firebase can now be bound to your controller e.g.
itemsService.setToScope($scope, 'items');
adapted PLUNKER

Resources