Sometimes I want to send simple events from the server to all clients in Meteor without having to deal with Collections - I feel like there must be some easy way to do this but I haven't managed to find it.
I want something like:
Server
connection.send("messageForAllUsers", {text: "Hello"});
Client
connection.subscribe("messageForAllUsers", function(result){
alert(result.text);
})
there is a meteor stream package which might be what you are needing.
http://arunoda.github.io/meteor-streams/communication-patterns.html#streaming_private_page
Take a look at this: http://meteorcapture.com/publishing-anything/
I think at the end of the day, collections is the easiest and most straightforward way to go when it comes to Meteor.
Related
Very simple and common use case, but I can't find satisfying answer.
I have react native app which needs to store some data locally. I am using redux and redux-observables and Realm as a storage.
What I need is: some action occur, let's say ADD_ITEM. I need to update UI with some payload (standard redux). Then I want to create/transform that payload to another piece of data and save that data into Realm (asynchronously). Whatever I try, it always lags UI (a lot).
I tried to wrap that realm call into promise and use switchMap, but it's still slow.
I haven't took a look at workers yet but they only accept strings, which is let's say much less usable for me.
I can offload completely that computation to native background thread but that will be very uncomfortable and a lot of writing.
Could async await help me? Of redux-saga? I feel like it's the same thing, not real async processing.
Or am I using completely wrong libraries for this?
const insertOrderItem = (action$) =>
action$.ofType(Action.ADD_ORDER_ITEM)
.switchMap(({ payload }) => Rx.Observable.fromPromise(
new Promise((resolve, reject) => {
storage.insert(createObject(payload)
resolve({
type: "OPERATION_ADDED"
})
})
))
In general, storing small piece of data to realm shouldn't be THAT much computational heavy but I feel like it's necessary to do this kind of jobs on background thread.
Am I missing something?
Thanks
I had same problem with my app using React Native + Realm DB. I tried all ways without having to write native code and make the bridge from react-native to native, and finally I found a solution:
https://corbt.com/posts/2015/12/22/breaking-up-heavy-processing-in-react-native.html
Install npm install next-frame --save.
Add next-frame to your code import nextFrame from 'next-frame';
Add this line within a for that took long, or a for which insert in DB await nextFrame();
A complete example would look like this:
import nextFrame from 'next-frame';
let response = await fetch("https://emberall.com/user/1/recordings");
let responseJSON = await response.json();
for (let recording of responseJSON.recordings) {
await nextFrame(); // The javascript will yield here and not resume execution until the next frame.
mergeRecordingToLocalDatabase(recording);
}
Basically what this does is that in every iteration or db-insert it waits for JS to render and process next UI frame, so your app will not get stuck or freeze.
P.D.: I know months have passed since question but I think a lot o people could benefit from this.
It's laggy because JS run in one thread. So if you wrap your code in Promise, it's still in one thread.
I think best solution for your is transfer data over React Native bridge to native and do this transform in native code. For guide how to communicate with native code look here
I'm not familiar with Realm, but I can't seem to find the storage.insert API you're using. I only see realm.write() transactions. I was trying to see if they had a truly non-blocking, asynchronous API but it appears Realm does not offer one for their JavaScript bindings.
They do appear to offer non-blocking APIs in their Java bindings with executeTransactionAsync() but that is not likely an option for you.
Seems like your options would be: do it in native on another thread, or some how reduce the write overhead (smaller object, write at a time where it's not noticeable, etc)
First - I am having a hard time formulating this question, so please bear with me, and ask for clarification and I'll try to provide as much as I can. I am just starting to learn meteor, so be patient please.
I have several inputs that save immediately as people type on them. (with a slight 300 ms delay to not overload database).
Basically, on "keyup" it goes and saves. All that works fine. However, I'd like to add a visual indicator (say a green checkmark, or a tiny "saved") when the database actually stores what they typed.
Graphically:
[___________________]
[Typed something_____] (saved)
[___________________]
I am not sure how to go about this, but it's something common, that plenty of you have already done. If I didn't care about the database feedback, I'd just use JQuery, target a class beside the input and make the checkmark or word visible after a keyup, or add it to the DOM. Fairly straight forward.The only when I am sure it has been stored in Mongodb part confuses me.
Any help would be gladly appreciated.
Thank you
Addendum with code:
Template.dibs.events({
'keyup input.name': _.throttle(function(event) {
Dibs.update(this._id, {$set: {name: event.target.value}});
$(':focus + .glyphicon-ok').css('opacity',1);
}, 300),
Can you explain where/how you would add the code? (For spinner, or the words).
Coming from JQuery I did something that I know is not the right way. This is in the client portion (I know just demo code, and it's not secure) but I wanted to know the best way leveraging meteor to do it. I already have checkmarks stating it was saved in the page, but they are all hidden, this code just makes them visible on keyup for the field.
I read through the article, and didn't quite see how I'd go about doing the intermediate step (spinner or the like) then the finalized checkmark after code is saved. I've also being going through the new 1.0 tutorial (which is great) but I'm still missing the visual indicators. It's great that meteor updates the UI if it fails in the server to reflect that it didn't save, since I am assuming success, I don't think that tapping into the Meteor.Error makes sense. Should there not be a Meteor.Success or equivalent?
Again, I apologize for the long message, I'm trying to wrap my head around this, because the technology looks very promising
Welcome to Meteor! Meteor was in fact designed (among other things) to handle just this type of situation, via a mechanism called Latency Compensation. You can read more about it at Meteor.methods.
Calling a method on the server requires a round-trip over the network. It would be really frustrating if users had to wait a whole second to see their comment show up due to this delay. That's why Meteor has a feature called method stubs. If you define a method on the client with the same name as a server method, Meteor will run it to attempt to predict the outcome of the server method. When the code on the server actually finishes, the prediction generated on the client will be replaced with the actual outcome of the server method.
You can use Latency Compensation by defining a Meteor method to save the input text to the database, with a client stub that displays a spinner instead of "saved", and "saved" when its callback is called successfully.
Alternatively, you can call the update method on the collection directly, and add a callback on the client, which will be called with (error, numberOfDocsUpdated) after the server method returns.
Read more on when to use Meteor methods and when to use client-side operations.
As Dan has said, the Latency Comp takes care of needing to do this. Another way of doing this is in a template event. You can set a session variable on keyup with the contents of the text field and in the helper, set a flag that will render the checkmark when the session variable and current user input matches.
I would like to retrieve Data from a remote api (via HTTP.get) and pass it to the client. Currently I manually poll the data and implemented some template helpers, that pass the data to the views.
In case of a jquery datatable I use the jquery-datatables package and that needs a published collection.
Has anyone a hint for me how to implement this?
Just for others who might want to know how to solve this:
You'll find an example here: https://github.com/avital/publish-time/blob/master/publish-time.js
The code is shown in this 20 min video: https://www.youtube.com/watch?v=onCkNRE2q0c
With that you'll be able to quickly implement custom publish/subscribe without using MongoDB.
#richsilv: Thanks again for pointing me to the right stuff.
I wonder what is the best way to do something like this:
When one of the data gets remove, all client will play an animation (like fading out the data, etc), or call a javascript function on client.
The cursor.observeChanges callbacks are exactly what you need in your client code to achieve this - specifically the removed callback. Have a look at the example provided in the docs and it should be quite straightforward.
What is the best practice for calling autosubscribe client side in a Meteor app?
Should it always be in Meteor.startup?
If so, why?
If not, why?
If sometimes, why?
In summary, what is the best practice and what are the trade offs based on the options of putting autosubscribe in the meteor.startup versus not? I think this is very important at this time for application developers because it significantly affects our application design decisions.
Autosubscribe has been deprecated and I suspect you want to use autorun now,. It's documented at http://docs.meteor.com/#meteor_autorun
When you want to automatically update the subscription whenever the session variable changes.
Source: From the comment in the example at Meteor.autosubscribe.
From tests I have done it does seem that putting your autosubscribe in Meteor.startup is the safest solution if you need those collections to have some kind of data population or start populating before view rendering. I experienced similar issues that #matb33 has reported with empty data on load and placing autosubscribe in Meteor.startup on the client solved the problem.
Note that autosubscribe is now gone, and replaced with autorun.