-
Notifications
You must be signed in to change notification settings - Fork 397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question about Promise adaptor #2983
Comments
Unfortunately there's not really a way for adaptors to do that. The Promise returned from I think the best solution here would be a monkey-patch: const realSet = Ractive.prototype.set;
Ractive.prototype.set = function(keypath, value, options) {
if (value instanceof Promise) return Promise.all([value, realSet.call(this, keypath, value, options)]).then(function(arr) { return arr[1]; });
return realSet.call(this, keypath, value, options);
} Most of the API methods on the Ractive prototype are just sugaring internal functions, so it's generally pretty safe to add more sugar on top. |
@evs-chris, hi and thanks for the answer! It's little bit sad that adaptors can't be used for this purpose. How to you think, maybe this feature need to be included in Ractive itself? I suppose that because promises are very useful and widespread thing right now. Many-many libraries and modules supports it and it can improve Ractive's set() capability. One more, it really strange to me, that ractive.set() resolve a promise without value which was set. I mean that ractive.set().then() doesn't have any arguments. I think more useful something like this:
|
This is because the promise returned by
The real problem is that there's actually two But then, that's what adaptors are for. If this feature needs to exist, it would be best implemented on that adaptor. I would imagine that |
@fskreuz hi and thank you too!
Yea, I know, but it's strange too because if I do set operation and this method returns some promise I undoubtedly expect that this promise relates to this operation. I can happen after a transition, it's ok, but promise itself need to be related to set operation. It's more obvious behaviour I think. Additional question, where can I get changelog for 0.9.0 version? I just install it from npm and all my project became a broken. Whether there are some breaking changes in this version? |
There's a changelog file in the repo. I think we should add it to the package along with the readme next time for an easy lookup. |
There's a migration page in the docs with known breaking changes: https://ractive.js.org/get-started/migrating Let us know if there's something we missed! |
Thanks, guys! Unfortunately, I see not too encouraging trends in latest versions. In my opinion, of course, but it's completely up to you. Anyway, I've resolved most of the issues except one: when I build Reactive and other modules, using Webpack 2 I got a strange error on the client:
Debug in Chrome shows me that it's really true. Ractive itself looks like that:
My previous version is 0.8.14, webpack config the same. I guess why easing and transitions object was included to Ractive too:
But why Ractive become this strange object I don't understand. |
@PaulMaly what are the discouraging trends? Too many features, not enough features? |
0.9 includes an ES module bundle, and I think it's not getting along with webpack. I'm looking into that, though it may take me a bit as I've never used webpack before. |
Regarding the webpack issue, I've confirmed that everything works out using the ractive ES module bundle with something like: import Ractive from 'ractive';
const Component = Ractive.extend({
template: 'Hello'
});
new Component({
target: '#target'
}); is working. I think the issue is probably with the ractive-component-loader, if that's what's being used. I'll see if I can track that down and see what it's doing. |
@sabob Actually, isn't a lot to devote too much time to discuss it. I see that Ractive moves forward a little bit quicker than earlier. I don't like directives-based approach strengthening. I didn't like directives in Angular, I hate that in Vue. I hope that this approach won't become the cornerstone of Ractive. I don't like reduction of browsers support. I don't like some complications in Ractive's concepts. I think that Adaptors is a very useful thing but too weak than should be. I think that server-side capabilities also could be more advanced. I really like Ractive, I wrote much code with Backbone and Angular before. I tried Riot, React and Vue, but Ractive still my favourite tool. Yes, Ractive not so popular, not so big community and not a lot of modules for it. Ractive slower than most of these tools and have a big size. But Ractive always was most simple to understand and use tool. Minimum complexity, maximum usability, you know. @evs-chris I don't use ractive-component-loader. I just use Webpack to support CommonJS modules on the client and some other applied things like minification, etc.
Unfortunately, I can't use ES modules, because they are not supported by NodeJS. I use isomorphic approach and for me, it's very important. The main thing that previous version works fine on the same config, but a new version is not. Seems that an issue. |
I use CommonJS modules on client and server sides. So, I don't have any global Ractive in my Promise adaptor module. It just uses ractive instance argument of wrap function. |
This is the just the kind of feedback we need. 👍 I agree that Ractive can be simpler. I have my own opinions, but we'll have to save these up for 2.0. 🎉 For now, we need it to be stable and bug-free for a 1.0 release. |
@PaulMaly attempting to address some concerns:
Can you exapnd a bit on what you'd like to see more in regards to server-side capabilities? As far as ES modules, the one shipped with ractive now should only be picked up by systems that can use ES modules, like webpack and rollup. The UMD bundle is still the default, so it should be fine for both node and browser environments. @mpowell-atomic also had an issue, but got it resolved by deleting As for the adaptor needing access to |
The way I understand module management in Node is that once a module is loaded, anything else requiring it will refer to that loaded module and not some clone/duplicate/separate instance. Assuming everything loads the same adaptor module and Ractive, modifying the Ractive prototype from the adaptor module should modify it once and permanently... or at least that's the theory. I may be wrong tho :D const Ractive = require('ractive');
// Once this module gets required somewhere, monkey-patch Ractive.prototype.set
const realSet = Ractive.prototype.set;
Ractive.prototype.set = function(keypath, value, options) {
if (value instanceof Promise) return Promise.all([value, realSet.call(this, keypath, value, options)]).then(function(arr) { return arr[1]; });
return realSet.call(this, keypath, value, options);
}
module.exports = function MyAdaptor(){ ... } |
I don't remember when exactly new transition syntax was implemented but this syntax generates many additional directives. In my opinion, an old syntax of transitions was more laconic.
Wow, it's a great news! Thanks!
It would be very awesome! My comment based on this publications cycle: http://www.stefankrause.net/wp/?p=431
Yes, that's one of the things what I'm talking about.
Yes, modules are caching, but it's a strange architectural proposal. Right now promise adaptor depends only on arguments passed to it, and it's good practice. My guess, it would be much more preferable if it will be available out-of-box.
The main problem on the server side is not "How we render an app?", Ractive does this well, but "When we need to render an app and send the response?" If we try to create our components isolated from another code, components need to make async operations inside of it. On the client, it's not a problem, because of client fully asynchronous, but server response is not, we need to decide a point when we can send fully rendered app with all data, after all async operations inside of all components. I try to do something like this:
So, an app "ready" event will be triggered only when all promises from all components, which add themselves to be rendered on the server (some components or some async operations can be not added, if it's not necessary), will be resolved or rejected (when we'll try to resolve them on client). But, it's not working right now, because set operation promise resolving at the wrong time with wrong value. To do that, we need to resolve this promise only then the actual value will be set even if it's an another promise. And this promise needs to be resolved with the actual value, not with undefined or transition things. |
Difficult to balance simplicity vs expressiveness... Not sure if it is too late to revert some complexity but a "Best Practice" guide might be useful to show idiomatic Ractive template syntax. |
@sabob "Best Practice" is a great idea! Most of the existing frameworks provide only "hello world" things, but Ractive always had an interactive tutorial and I think "Best Practice" which solves main development issues, will be very useful to start with Ractive. |
As of 0.9.1, you can access the |
|
Oddly enough, it seems startup time is our worst metric now. I think using the ractive-bin-loader in the webpack config would result in a significant drop (maybe half) in startup time because parsing isn't exactly cheap. |
Fun observation: Ractive's implementation appears to be purely runtime... while the benchmark is against compiled/half-compiled implementations. Not too bad really. :P btw, i'd avoid hijacking the thread. :P |
I use fully pre-compiled templates during packaging via Webpack. How do you think how much acceleration it gives as a result? |
And one more point about this case:
Unfortunately, it's still happening. And I don't know what I can do with this. CommonJS still more convenient for me to include dependencies. On the server-side everything OK, but on the client, I see this object instead Ractive constructor:
Maybe you know what does it mean? Maybe it will help you: Can we somehow prevent this problem? I will be very grateful if you provide a solution. |
The issue is that [webpack doesn't support default exports in a configurable way] (webpack/webpack#4742), so we may need to drop the module field from our package manifest if we need to support commonjs in bundlers. I think that's not a particularly good solution though. You can probably set up an alias or something like it to make sure you get the cjs build of ractive rather than the es build. |
Ok, but why I don't get this issue using other libs? Most of them work well with both - CommonJS and ES6.
It seems I did not fully understand this point, could you please provide more details? |
Seems, it can be fixed via Webpack config. FYI:
|
Hi, all! I'm using Promise adaptor and basically, it's a nice tool to set some async values right into Ractive data. But now I want to use built-in Promise returned by ractive.set() method.
The problem is that this promise resolved instantly, before Promise adaptor's resolved real value. But I want to do something like this:
ractive.set('items', api.get('items')).then(() => { /* do something with real values */ })
Is any ideas how to rewrite Promise adaptor to support this behaviour?
The text was updated successfully, but these errors were encountered: