State, refs or session for passing global data to component

Hey guys,

I’m basically testing my newb Meteor skills out by building a few things, one of which is a simple chat room.

I’m detecting when the user enters text into the message box and passing the username and some text into setState :

Init the state in constructor :

this.state = {
      isTyping: ''
}
// when user types function.....
this.setState({
      isTyping: Meteor.user().username + ' is typing...'
})

I then echo the state to all clients in render :

<p>{this.state.isTyping}</p>

But as I’m sure you’ve already guessed, this renders the client’s own username in every browser, regardless of which user is actually typing.

  1. Is state the wrong thing to be using here?
  2. Should I be using ref or Session instead?
  3. Isn’t using either of those also going to result in the same problem?
  4. Am I going about this in completely the wrong way?

Yeah, those won’t fix your problem either, as they will only affect that one client on his own computer.

You will need to send that state to the server somehow, either though saving that state to the database (in the user document for example, as an isTyping field), or use an event system that sends the event to the server, and on to the other users in the room.

The database approach is pretty simple to set up, while the event system will take some more work, but will perform better in the long run.

Thanks for the clarification.

Events system sounds like the best approach for sure.

How would those events be stored server side if not in a collection though? In a global Session or global state (if such a thing exists)?

Do you know of a basic example of using an event system in a similar way somewhere that I can read and learn from?

Session and state are based on the user and not shared universally. You have to save it server-side on a data store like in MongoDB so that other users can have access to it

Have you seen the socialize:messaging package? It has typing status as a feature which works for multiple participants in a conversation and can either use the database to pass typing state, OR if redis-oplog is installed and configured it will bypass the database and and use a redis-oplog channel to pass the status to clients in the same fashion as what I would imagine in event system would.

1 Like

That sounds great, will check it out. Thank you!

Very welcome. Even if you don’t end up using the package, you can have a look at how it’s done and get some ideas on how you might accomplish it. Code is available at https://github.com/copleykj/socialize-messaging

That’s exactly what I was going to do! The more working examples I can see of things I’m stuck on is really going to help.

Absolutely! Just in case you want working examples of any of the socialize packages, there is https://github.com/copleykj/meteor-socialize-demo which can be cloned an ran.

1 Like

Just saw that you are the author of this! Respect bro :fist_right:

1 Like

Thanks! :slight_smile:

I’ve authored and/or maintain around 20 packages. Most of the socialize packages are also ported to NPM for use with React Native and are just waiting for @aldeed to merge pull requests on 2 of his packages and issue releases before they can work fully. Once that happens you’ll be able to have socialized RN apps that connect to your meteor server and share the same API across both.

2 Likes

Forgive my ignorance, I’m new around these here parts, didn’t realise that I was talking with a Meteor OG!
I’ve seen @aldeed’s name all over the place on my travels too. Very cool that you guys are in here mingling in steerage with us :rofl:

Just been peeping out the socialize demo. Very very cool! Packed with features that I’m sure is going to make it a must have for anybody wanting an out of the box social aspect to their project. Must have taken ages to put this together.

Thanks once again for the heads up on this, this is going to invaluable for my current Meteor journey!

I have a feeling I’ll be watching and following everything you do from now on :grin:

Just popped some LTC lovin’ your way too.

1 Like

HAHA! I don’t think I’d say I’m a Meteor OG :slight_smile: I’ve been working with meteor since the 0.5 release so I’ve been around a while, but I’m no Arunoda Susiripala, Chris Mather, or Josh Owens :joy:

Thanks for the contrib offer, that’s super awesome of you!

1 Like

Received! Very much appreciated!

Most welcome bro :wink:

Gotta support the OSS (Open Source Soldiers)!

1 Like

@copleykj Ahh man just found this in your repo too!

You have no idea how much of a drama I’ve had trying and failing to get Cloudinary working properly by importing their packages. In the end I had to do a super ugly hack to get it working. Gonna install this over the weekend and give it a spin instead! Thanks again :slight_smile:

Awesome man! Yeah, I fought with other cloudinary packages for quite awhile, but never really found one that didn’t have extraneous dependencies or unsatisfactory API’s. Async/Await support is probably my fav part of the whole package.

1 Like

@copleykj which PRs? Sorry I’m a bit behind

No problem man, I know how busy you are. The one for simple-schema looks to be merged actually. The other is on node-mongo-object.

Hi there,

There are a few things you need to do to get this to work.

Assuming you have removed the packages that publish all data from your code, your client side code only has access to the logged in user’s details and no one else’s (unless you specifically publish this data from the server for users to subscribe too, and then you need to think about only publishing Profile data). So other people are never going to be able to see the name of a different user via the method you have above.

What I would do is update the messages thread document in the mongo collection you have for the messages with the user’s details who has just started to type. You can create a new Meteor Call for this.

Other logged in users would then get this data because they would also be subscribed to the message thread collection, and you would be able to display the name for them.

Given multiple people can view viewing, the ‘isTyping’ should be an array I guess.

1 Like