breeze fetch meta data if not present - angularjs

I have an angular / breeze / webapi app which works great except if I refresh a page which has a EntityQuery to return one entity. It then complains that the metadata is not available as the entityquery does not trigger a metadata fetch, unlike a standard query.
If we have reached the page from a previous angular page which has fired a standard breeze query then the metadata is already there and we have no problem.
So question is, how do I check the metadata exists and trigger the metadata call if it is not already done?
Many thanks for any help you can give me.

Try something like this:
function fetchMetadata() {
var manager = new breeze.EntityManager("api/breeze");
if (manager.metadataStore.isEmpty()) {
return manager.fetchMetadata();
}
return Q.resolve();
}
function start() {
fetchMetadata().then(function () {
// Metadata fetched.
// Do something here.
});
}

Related

Angularjs 1: delete an item, but item still exist until refresh

Here is my simple angular 1 app.
Source code here.
Basically it is a copy of this.
I am able to do CRUD operations. The issue is that, when I delete a record. It redirects back to the home page. The record I deleted is still here. If I refresh the page, it is gone.
Is it a way to delete a record and then after redirect, I should see the latest list?
Update 1:
Unfortunately, it is still unresolved. Something strange that it seems the promise in resolve is cached. I added a few console.log inside the code. You can see the code flow. Open chrome developer tool to see it.
i review you code , the problem is here:
this.deleteContact = function(contactId) {
var url = backend_server + "/contacts/" + contactId;
// actually http delete
return $http.delete(url)
.then(function(response) {
return response;
}, function(response) {
alert("Error deleting this contact.");
console.log(response);
});
}
if you have service to manage your contact use there to call your server to delete the contact.
the reason you cannot delete without refresh is:
your delete from DB but not from angular array.
must review (update the scope (array))
your code is hard to read , i have suggestion for you, using:
broserfy , watchify
lodash
and backen use mvc
You delete it remotely but not locally. So you can see result only after refreshing (only after you requesting updated data from server). You need to update your local contacts after you succeed on server side.
$scope.deleteContact = function(contactId) {
Contacts.deleteContact(contactId).then(function(data){
...
//DELETE YOU LOCAL CONTACT HERE
...
$location.path("/");
});
}
I didn't look deeply into your code, so I can't say how exactly you should do it, but as I see you keep your local contacts in $scope.contacts in your ListController.

Publish/Subscribe not working automatically when data added to the mongodb

I have the following publisher and subscriber code.
It works for the first time when the app starts, but when I try to insert data directly into the Mongo database, it will not automatically update the user screen or I don't see the alert popping.
Am I missing something?
Publish
Meteor.publish('userConnections', function(){
if(!this.userId){
return;
}
return Connections.find({userId: this.userId});
})
Subscribe
$scope.$meteorSubscribe('userConnections').then(function () {
var userContacts = $scope.$meteorCollection(Connections);
alert("subscriber userConnections is called");
if (userContacts && userContacts[0]) {
....
}
}, false);
First off, if you are not using angular-meteor 1.3 you should be. The API has changed a lot. $meteorSubscribe has been deprecated!
To directly answer your question, $meteorSubscribe is a promise that gets resolved (only once) when the subscription is ready. So, it will only ever be called once. If you look at the documentation for subscribe you'll see how to make the binding "reactive", by assigning it to a scope variable. In your case it would be something like:
$scope.userContacts = $scope.$meteorCollection(Connections);
Doing it this way, when the collection gets updated, the $scope.userContacts should get updated as well.

Issues with single-requests in Restangular

I'm having a slight issue with my ability to consume REST data retrieved via Restangular in an angular controller. I have the following code which works fine for a list of accounts:
var baseAccounts = Restangular.all('accounts');
baseAccounts.getList().then(function(accounts) {
$scope.accounts = accounts;
});
This works perfectly for a list. I use similar syntax for a single account:
var baseAccount = Restangular.one('accounts');
baseAccount.getList(GUID).then(function(returnedAccount) {
$scope.currentAccount = returnedAccount;
});
I am using ng-repeat as the handling directive for my first request. I am attempting to bind with {{ account.name }} tags for the single request, but it does not seem to display any data despite the request being made properly. GUID is the parameter I must pass in to retrieve the relevant record.
I have combed through Restangular docs and it seems to me like I am composing my request properly. Any insight would be greatly appreciated.
EDIT: I've tried all of the solutions listed here to no avail. It would seem Restangular is submitting the correctly structured request, but when it returns it through my controller it shows up as just a request for a list of accounts. When the response is logged, it shows the same response as would be expected for a list of accounts. I do not believe this is a scoping issue as I have encapsulated my request in a way that should work to mitigate that. So, there seems to be a disconnect between Request -> Restangular object/promise that populates the request -> data-binding to the request. Restangular alternates between returning the array of accounts or undefined.
Have you looked at:
https://github.com/mgonto/restangular#using-values-directly-in-templates
Since Angular 1.2, Promise unwrapping in templates has been disabled by default and will be deprecated soon.
Try:
$scope.accounts = baseAccounts.getList().$object;
try:
var baseAccount = Restangular.one('accounts', GUID);
baseAccount.get().then(function(returnedAccount) {
$scope.currentAccount = returnedAccount;
});
The problem here is that it's expecting an array to be returned. I'm assuming that you are expecting an account object. Thus we need to use the get function, intead of getList()
The one() function has a second argument that accepts an id e.g. .one('users', 1). You can take a use of it.
CODE
var baseAccount = Restangular.one('accounts', 1); //1 would be account id
baseAccount.getList('account').then(function(returnedAccount) {
$scope.currentAccount = returnedAccount;
});
OR
var baseAccount = Restangular.one('accounts', 1); //1 would be account id
baseAccount.all('account').getList().then(function(returnedAccount) {
$scope.currentAccount = returnedAccount;
});
For more info take look at github issue
Hope this could help you, Thanks.

Store is loaded twice after data.Model.save()

I have a grid with remote data (php/mysql/json) and use a form to insert records or to edit this data.
I use the api configuration of the proxy/store. I use MVC architecture.
So, all very simple (in pseudo code):
get selected model form grid or create model
frm.loadRecord()
frm.updateRecord()
frm.getRecord().save()
and all works fine, but I noticed in the browser console that after the POST (works fine, calls either the url configured with create or the url configured with update), the store calls (GET) the url configured with retrieve twice. These calls are identical.
So functionally all works fine and I could ignore it, but now I've noticed I want it fixed.
Can anyone help me where to look? Thanks in advance.
Details:
It's all really basic:
In the controller of the gridpanel:
updateRow: function (gridpanel) {
var sm = gridpanel.getSelectionModel();
var record = sm.getLastSelected();
this.showForm(record);
}
and
showForm: function (record) {
...
formpanel.show();
var frm = formpanel.getForm();
frm.loadRecord(record);
}
In the controller of the formpanel:
submit: function(frm) {
frm.updateRecord();
frm.getRecord().save();
}
When I remove the save action the GET requests aren't called, so this seems to trigger them.
In the store:
api: {
create: '../php/api/customers.php?request=create',
read: '../php/api/customers.php?request=retrieve&scope=summary',
update: '../php/api/customers.php?request=update',
destroy: '../php/api/customers.php?request=delete'
}
The screenshot:

How to fetch and populate backbone model for Google Places JS API?

I'm implementing a system that require access to Google Places JS API. I've been using rails for most of the project, but now I want to inject a bit of AJAX in one of my views. Basically it is a view that displays places near your location. For this, I'm using the JS API of Google places. A quick workflow would be:
1- The user inputs a text query and hits enter.
2- There is an AJAX call to request data from Google Places API.
3- The successful result is presented to the user.
The problem is primarily in step 2. I want to use backbone for this but when I create a backbone model, it requests to the 'rootURL'. This wouldn't be a problem if the requests to Places was done from the server but it is not.
A place call is done like this:
service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
Passing a callback function:
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
var place = results[i];
createMarker(results[i]);
}
}
}
Is it possible to override the 'fetch' method in backbone model and populate the model with the successful Places result? Is this a bad idea?
It is possible to override the fetch method of your backbone model.
var mapModel = Backbone.Model.extend({
fetch: function (options) {
// do your call to google places here
},
callBackFunctionForGoogleMaps: function (results, status) {
// call back function here would set model properties
}
});
return mapModel;
This way you override fetch and remove the defaults behavior of Backbone to make an ajax call.
Just as an FYI if you want to override Backbone models fetch but still have the default behavior of model.fetch you can do the following. Note the return calling Backbone.Model.fetch.
var mapModel = Backbone.Model.extend({
fetch: function (options) {
// do any pre-fetch actions here
return Backbone.Model.fetch.call(options);
}
});
return mapModel;
It is probably not a bad idea to override the fetch method here because you are still fetching data for your model, just not through ajax calls on your end. It would be smart though to leave comments noting that you are overriding fetch in this manner for a reason.

Resources