Deleting records with Basic Adapter - ember.js

I'm looking at implementing Model.sync.deleteRecord() for use with Ember-Data Basic Adaptor.
According to the docs, adapter must call didDeleteRecord() once record has been successfully deleted from the server.
However, I can't find good example on how to actually call didDeleteRecord(). After looking at the source, the best I come up with this:
deleteRecord: function(record, process) {
my_api.remove(record.get('id')).then(function() {
var r = process(record);
r.store.adapter.didDeleteRecord(r.store, r.type, r.record);
});
}
Is there any better, less uglier ways to call didDeleteRecord()?

Related

loopback operation hook: add filter to count api

I need to intercept my loopback queries before they query my Mongodb to add additional filters, for example, to limit the object to what the user has access to.
I can successfully update the query on access operation hook to add filters to the GET /Applications , where Applications is my object. However This fails to work for GET /Applications/count
The command runs with a 200, however it returns zero results, even though I'm adding the exact same filters. There most be something different about count that I'm missing. The ctx object looks have a ton of functions/objects in it. I'm only touching the query property, but there must be something else I need to do.
Any ideas? Thank you, Dan
Could you please share your access hook observer's implementation. I tried it on a sample app, and following access hook works as expected for /api/Books/count:
module.exports = function(Book) {
Book.observe('access', function logQuery(ctx, next) {
ctx.query.where.id = 2; // changing filter value for where
console.log('Accessing %s matching %j', ctx.Model.modelName, ctx.query.where);
next();
});
};
Verify that you're modifying query property of Context (see access hook).
Hope that helps.

ember-data 2.0 and Offline

I am creating a new ember app. I want to use the newest version of ember-data. (ember-data 2.0). I want it to be a mobile webapp. Therefore it must handle variable network access and even offline.
I want it to store all data locally and use that data when it goes offline so the user gets the same experience regardless of the network connectivity.
Is ember-data 2.0 capable of handling the offline case? Do I just make an adapter that detects offline/online and then do....?
Or do I have to make my own in-between layer to hide the offline handling from ember-data?
Are there any libraries out there that has this problem solved? I have found some, but are there any that is up to date with the latest version of ember-data?
If device will go offline and user will try to transition to route, for which model is not loaded yet, you will have an error. You need to handle these situations yourself. For example, you may create a nice page with error message and a refresh button. To do this, you need:
First, In application route, create error action (it will catch errors during model hook), and when error occurs, save transition in memory. Do not try to use local storage for this task, it will save only properties, while we need an actual transition object. Use either window.failedTransition or inject in controllers and routes a simple object, which will contain a failed transition.
actions: {
error: function (error, transition) {
transition.abort();
/**
* You need to correct this line, as you don't have memoryStorage
* injected. Use window.failedTransition, or create a simple
* storage, Iy's up to you.
*/
this.get('memoryStorage').set('failedTransition', transition);
return true; //This line is important, or the whole idea will not work
}
}
Second, Create an error controller and template. In error controller define an action, retry:
actions: {
retry: function () {
/**
* Correct this line too
*/
var transition = this.get('memoryStorage').getAndRemove('failedTransition');
if (transition !== undefined) {
transition.retry();
}
}
}
Finally, In error template display a status and an error text (if any available) and a button with that action to retry a transition.
This is a simple solution for simple case (device gone offline just for few seconds), maybe you will need something way more complex. If you want your application to fully work without a network access, than you may want to use local storage (there is an addon https://github.com/funkensturm/ember-local-storage) for all data and sync it with server from time to time (i.e sync data every 10 sec in background). Unfortunately I didn't try such things, but I think it is possible.

How to get notified on model changes in generic way with ember data

I am using Ember and Ember Data and I would like to listen to any changes relevant for a specific model.
For example in my app I could have an Order model with two fields - attr1 and attr2.
The two use cases/questions are:
How to get notified when new Order instances get added or deleted to/from store. Something like store.on(modelName, 'deleted/added', listener). modelName in this case would equal 'order'.
How to get notified on any change within all models of specific type in the store. Something like store.on(modelName, 'modelUpdated', listener). I don't want to specify in which attributes I am interested because I am interested in any change in any attribute.
Any ideas and pointers are really appreciated.
ember-data provides lifecycle callbacks for DS.Model objects. Have a look to the events panel of the doc.
You can extend the store to achieve the behavior in point 1. We will use an event name of "added:modelName".
this.store.reopen(Ember.Evented, {
createRecord(model) {
this.trigger('added' + ':' + model);
return this._super(...arguments);
}
}
Point 2 is harder.
To listen from somewhere:
listen: function() { this.store.on('added:order'), this.handleAddedOrder; }

Ember.js Data how to clear datastore

I am experiementing with Ember.js and have setup a small app where users can login and logout. When the user logs out I want to clear all of the currently cached records in the Data Store.
Is there a way to do this or would I have to force the browser to reload the page?
I know this question is from 2013. But since Ember Data 1.0.0-beta.17 (May 10, 2015) there's a straightforward way of clearing the datastore:
store.unloadAll()
(More here: http://emberigniter.com/clear-ember-data-store/)
It looks like, as of today, there is still no generic way of fully forcing a store cleanup. The simplest workaround seems to loop through all your types (person, ...) and do:
store.unloadAll('person');
As seen here
Clearing the data store is not yet supported in Ember-Data. There is an open issue concerning this on the Github tracker.
A cleaner & generic approach. Just extend or reopen store & add a clear method like this.
DS.Store.extend({
clear: function() {
for(var key in this.typeMaps)
{
this.unloadAll(this.typeMaps[key].type);
}
}
});
There is:
App.reset();
But that does more than clear out the data store and we've occasionally seen errors where store.pushPayload tries to push data onto an object marked destroyed from calling App.reset();.
Been we've been using:
store.init();
Which just creates a new empty store and works great but unfortunately is a private method.
This can now be done with store.destroy(). It unloads all records, but it also available for immediate use in reloading new records. I have confirmed this as of 1.0.0-beta.15. It doesn't appear to be in the documentation, but it's been working for me.
The alternative would be iterating the store's typeMaps and running store.unloadAll(typeMap.typeName), but I'm not sure it's entirely necessary.
Deleting record by record in model. deleteOrgs of this jsBin:
deleteOrgs: function(){
var len;
while(len = this.get('model.length')) {
// must delete the last object first because
// this.get('model.length') is a live array
this.get('model').objectAt(len-1).deleteRecord();
}
this.get('store').commit();
}
( As of August 2013, there is currently a problem with lingering deleted data. )

How to manually set a primary key in Doctrine2

I am importing data into a new Symfony2 project using Doctrine2 ORM.
All new records should have an auto-generated primary key. However, for my import, I would like to preserve the existing primary keys.
I am using this as my Entity configuration:
type: entity
id:
id:
type: integer
generator: { strategy: AUTO }
I have also created a setter for the id field in my entity class.
However, when I persist and flush this entity to the database, the key I manually set is not preserved.
What is the best workaround or solution for this?
The following answer is not mine but OP's, which was posted in the question. I've moved it into this community wiki answer.
I stored a reference to the Connection object and used that to manually insert rows and update relations. This avoids the persister and identity generators altogether. It is also possible to use the Connection to wrap all of this work in a transaction.
Once you have executed the insert statements, you may then update the relations.
This is a good solution because it avoids any potential problems you may experience when swapping out your configuration on a live server.
In your init function:
// Get the Connection
$this->connection = $this->getContainer()->get('doctrine')->getEntityManager()->getConnection();
In your main body:
// Loop over my array of old data adding records
$this->connection->beginTransaction();
foreach(array_slice($records, 1) as $record)
{
$this->addRecord($records[0], $record);
}
try
{
$this->connection->commit();
}
catch(Exception $e)
{
$output->writeln($e->getMessage());
$this->connection->rollBack();
exit(1);
}
Create this function:
// Add a record to the database using Connection
protected function addRecord($columns, $oldRecord)
{
// Insert data into Record table
$record = array();
foreach($columns as $key => $column)
{
$record[$column] = $oldRecord[$key];
}
$record['id'] = $record['rkey'];
// Insert the data
$this->connection->insert('Record', $record);
}
You've likely already considered this, but my approach would be to set the generator strategy to 'none' for the import so you can manually import the existing id's in your client code. Then once the import is complete, change the generator strategy back to 'auto' to let the RDBMS take over from there. A conditional can determine whether the id setter is invoked. Good luck - let us know what you end up deciding to use.