Vadim Novozhilov Vadim Novozhilov - 1 year ago 51
React JSX Question

Meteor + React, show specific content based on user’s actions

I'm working on an app that contains send/cancel request functionality.
I have the following code:

import React, { Component, PropTypes } from 'react';
import { Events } from '../../api/collections/events.js';
import { Visitors } from '../../api/collections/visitors.js';
import { createContainer } from 'meteor/react-meteor-data';

class Event extends Component {
handleDelete() {
requestInvite() {
let eid = Events.findOne(this.props.event._id).title;
visitor_id: Meteor.userId(),
visitor_email: Meteor.user().emails[0].address,
event_name: eid,
// did it to debug function, returns correct value
console.log(Visitors.findOne({id: this._id}) + ', ' + Meteor.userId());
cancelInvite() {
render() {
const visitor = this.props.visitor.visitor_id;
const length = Visitors.find({}).fetch().length;
return (
{this.props.event.owner == Meteor.userId() ?
<img src={this.props.event.picture} />
<button onClick={this.handleDelete.bind(this)}>Delete</button>
</div> :
<img src={this.props.event.picture} />
{ length > 0 && visitor == Meteor.userId() ?
<button onClick={this.cancelInvite.bind(this)}>Cancel Request</button>
<button onClick={this.requestInvite.bind(this)}>Request invite</button>

Event.propTypes = {
event: PropTypes.object.isRequired,
export default createContainer(() => {
return {
event: Events.findOne({id: this._id}) || {},
visitor: Visitors.findOne({id: this._id}) || {},
}, Event)

It works quite simple, this component shows action buttons depend on user's status (if the current user hosts this event, it shows
related functionality and so one, I just keep is as simple as it can be for this example). If the current user isn't this event's hoster, component lets this user to send (and cancel) a request for invite. Okay, everything works as it should but only for the first user clicked on
Send Request
button and after that ich changes to
Cancel Request
(I use different browsers to test cases like this). The rest of users can also click on
Send Request
but for them it doesn't change to
Cancel Request
(but it still adds correct document to
collection, also I have a component which displays all the visitors and the data is corret, i.e ids, emails and event titles). By the first time I thought it's an issue with
function, but I don't think so because
console.log(Visitors.findOne({id: this._id}) + ', ' + Meteor.userId());
's output stays correct giving me current user's id and just created visitor's id which are the same for each case. Also I found a very strange behaviour. When the app rebuilds, send/cancel functionality works as it suppossed to for every single user.
I think I'm kinda close for the solution but need a little gotcha to do it.
Any help would be highly appreciated!


It's obvious that my question isn't full without describing
document being created in this component. Here it is:

"_id": "Qbkhm9dsSeHyge4rT",
"visitor_id": "qunyJ4sXNfz2w8qeR",
"visitor_email": "",
"event_name": "test",

So as you can see I grab
and that's why I'm using
to check if currently logged in user's id is equal to a particular visitor's id.


The problem was with my query to fetch visitor's ids in
function. I changed it to
visitor = Visitors.findOne({visitor_id: Meteor.userId()})
and it worked the way I described.

Answer Source

Without knowing how your Visitors collection documents are structured, it's difficult to say for sure; however, it seems that your condition for visitor == Meteor.userId() is the issue since you said that the documents are correctly being added to the Visitors collection, which would make length > 0 return true.

The issue could be that you are setting const visitor = this.props.visitor.visitor_id; rather than say const visitor = this.props.visitor._id;.