Comments (6)
👍
from ampersand-model.
We also don't need to propagate user data down into randomly required models and collections,
something quite painful to do in event-loop based async programming on node.
This is the really killer requirement!
from ampersand-model.
Hey @TimBeyer! There's a lot here, that I'm trying to get my head around, so bear with me if I'm misunderstanding you.
sync aka ampersand-sync is accessed from the closure scope in ampersand-model
This is true, however, it's only ever accessed by the sync
method, so if you want to not use ampersand-sync, and instead use something else, there's no reason you can't do:
var BaseModel = AmpersandModel.extend({
sync: function(method, model, options) {
//do whatever you want in here
}
});
If that's not enough, and you really don't want any of the sync stuff from ampersand-model, have you seen ampersand-state](https://github.com/AmpersandJS/ampersand-state)? It's basically ampersand-model but without any of the restful syncing stuff - which sounds like what you want, I think?
As to your original problem of how to handle user-specific tokens, we solve this at &yet by using the ajaxConfig options, and setting a base model up like this, as per ajaxConfig docs.
//some global-ish object to store your accessToken in:
app.me.accessToken = "{wherever you got the access token}";
var BaseModel = AmpersandModel.extend({
ajaxConfig: function () {
return {
headers: {
"Authorization": app.me.accessToken
}
}
}
});
But it's quite possible I've misunderstood what you're trying to do?
from ampersand-model.
So, let me try to explain:
I wanted to do exactly what you proposed:
use the raw ampersand-state
, add a url
method to it and then use external sync methods.
To re-use your code for fetch
, save
and destroy
, my plan was to just do
var Model = require('ampersand-model');
var fetch = Model.prototype.fetch;
var fetchState = function (state) {
return fetch.call(state);
};
But then it also needs this.sync
, so I cannot just call it on state
alone.
I'd need an object that delegates to the state
methods and properties (state.set
, state.parse
, state.trigger
etc etc) for everything except sync
, which needs to be overridden.
Basically what's really in the way is Model.prototype.sync
, which directly delegates to sync
- and looking back at my PR, I am actually no longer sure it would solve this problem. I'll close the PR.
The only solution I currently see is to not look for sync
on the prototype
, but to call it based on the dependency passed in, similar to what the PR suggested.
Regarding using ajaxConfig
on a BaseModel
:
This does not work on the server, unless you create new classes for every request, because many requests come in and are being worked on asynchronously, and they all need different authentication tokens for API requests. If you have a base class, everyone would share the same tokens.
If you create a new class for every request you have a new problem: If some other module wants to import this class and extend it, it cannot easily do that. It needs to wait for the 'personalized' class to be available, then export the subclass based on that.
All of this is a lot of overhead, and continuation-local-storage
, while being very elegant, kind of is a hack. The most solid and non-hacky, non-magicy way seems to be to just have a single component created per request that takes care of making all http calls for the models, and not allowing models to be instantiated just anywhere in the application, but only at the central sync manager.
from ampersand-model.
Regarding using ajaxConfig on a BaseModel:
Oh, sorry, I missed the point about being on the server.
Basically what's really in the way is Model.prototype.sync, which directly delegates to sync - and looking back at my PR, I am actually no longer sure it would solve this problem.
In that case can't you do something like:
var sync = require('ampersand-sync');
var AmpersandModel = require('ampersand-model');
var BaseModel = AmpersandModel.extend({
sync: function (method, model, options) {
//do whatever you need to
//...
// call original sync
sync(/*args*/)
}
});
Again, I'm sure I'm still not quite following you correctly, sorry! :)
from ampersand-model.
The thing is that I do not want a sync
method on the model, I want to basically use ampersand-state
only, in addition to the url
method. And I want to reuse the fetch
, save
and destroy
methods from ampersand-model
, but instead of having them on the instances / their prototype, I want an external component that calls them like syncMethods.fetch.apply(state, arguments)
, because I really don't want developers to even think about being able to directly save, fetch or delete a model.
The way it currently works, I end up with some monstrosity like this:
var Promise = require('bluebird');
var Model = require('ampersand-model');
var sync = function (method, model, options) {
// Imagine this actually does something
return Promise.resolve();
};
module.exports = function dataManager(options) {
var getSyncDelegator = function (sync, state) {
var syncMethod = function () {
return sync.apply(state, arguments);
};
var deleteSync = function () {
delete state.sync;
return state;
};
var syncable = {
save: function (key, val, options) {
state.sync = syncMethod;
return Model.prototype.save.call(state, key, val, options).then(deleteSync);
},
fetch: function (options) {
state.sync = syncMethod;
return Model.prototype.fetch.call(state, options).then(deleteSync);
},
destroy: function (options) {
state.sync = syncMethod;
return Model.prototype.destroy.call(state, options).then(deleteSync);
}
};
return syncable;
};
return {
save: function (state, key, val, options) {
var syncable = getSyncDelegator(sync, state);
return syncable.save(key, val, options);
},
fetch: function (state, options) {
var syncable = getSyncDelegator(sync, state);
return syncable.fetch(options);
},
destroy: function (state, options) {
var syncable = getSyncDelegator(sync, state);
return syncable.destroy(options);
}
};
};
Not relying on Model.prototype.sync
would turn this code into just this:
var Promise = require('bluebird');
var syncMethodsFactory = require('ampersand-sync-methods');
var sync = function (method, model, options) {
// Imagine this actually does something
return Promise.resolve();
};
module.exports = function dataManager(options) {
var syncMethods = syncMethodsFactory(sync);
return {
save: function (state, key, val, options) {
return syncMethods.save.call(state, key, val, options);
},
fetch: function (state, options) {
return syncMethods.fetch.call(state, options);
},
destroy: function (state, options) {
return syncMethods.destroy.call(state, options);
}
}
}
from ampersand-model.
Related Issues (20)
- Automatically setting collection and collection items parent for models initialized from JSON HOT 3
- success handlers dont get access to the actual http response
- Relative urlRoot
- wrapError stripping ampersand-sync's err.message. HOT 3
- When wait: true, serialization not applied to attributes passed to the save method. HOT 8
- Save options wait:true and patch:true are mutually exclusive HOT 4
- Use ampersand-sync 3.0.7 HOT 1
- Evaluate changes in ampersand-sync 4.0
- Adopt ampersand-sync v4.0
- A collection declared as a prop introduces errors. HOT 2
- Props array type doesn't update until after .save() HOT 3
- model.destroy() returning opts.success() with no DELETE xhr created HOT 3
- When using ampersand-model I cannot save a prop called `url` HOT 3
- Mixing in data for every request HOT 1
- local data HOT 4
- update ampersand-sync to 4.0.3
- Error when using latest ampersand-state HOT 2
- Incompatibility with Webpack?
- Missing attributes from server are not removed HOT 3
- Default content type to text/plain;charset=UTF-8 with ajaxConfig HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ampersand-model.