#StackBounty: #node.js #reactjs How can I initiate react to reload after a data change on the node js side?

Bounty: 100

Edit: It appears that my callback function from emit is never executed but not sure why.

So I added a calendar to react which changes the workout data to a specific date. When I change the date the data does change correctly. If I refresh the react web pages I get the updated data. I’m just a little confused on how to have node js initiate the data update in react. After changing the data I have node emitting to this socket…

//  Used for getting workouts for specific date. 
socket.on('GetWorkoutDate', async function (date) {
  workouts.getNewWorkouts(date.date)
  const screenWorkouts = workouts.current.filter(workout => workout.station == 1)
  console.log(screenWorkouts[0])
  socket.emit('UpdateWorkouts', screenWorkouts)
})

Then I the react side I tried something like this but no data change on the react.

import React, { Component } from 'react'
import { defaultTo } from 'ramda'
import openSocket from 'socket.io-client'

import './styles.css'

class Screen extends Component {
state = {
time: '',
rest: false,
workout: [],
queue: [],
}

componentDidMount() {
const screenNumber = this.props.match.params.id

this.socket = openSocket(`http://${window.location.hostname}:${process.env.REACT_APP_WEBSOCKET_PORT}`)
this.socket.on('connect', () => {
  this.socket.emit('joinRoom', 'screens')
  this.socket.emit('initScreen', screenNumber)
})
this.socket.on('timer', ({ time, rest }) => this.setState({ time, rest }))
this.socket.on('screenInfo', data => this.setState({ workout: defaultTo({}, data[0]) }))
this.socket.on('queueInfo', data => this.setState({ queue: defaultTo([], data) }))
this.socket.on('queue', ({ queue }) => this.setState({ queue: defaultTo([], queue[screenNumber - 1]) }))
this.socket.on('UpdateWorkouts', (updatedData) => this.handleUpdateWorkouts(updatedData));
}

componentWillUnmount() {
this.socket.close()
}

handleUpdateWorkouts = (updatedData) => {
this.setState({ workout: updatedData[0] })
 }

renderMovement = (movement, equipment) => {
if (!movement) return <noscript />

return (
  <div className="screenMove">
    {equipment && `${equipment.title} `}
    {movement.title}
  </div>
)
}

render() {
const { time, rest, workout, queue } = this.state
const variation = defaultTo({}, workout.variation)
const person1 = defaultTo({}, queue[0])
const person2 = defaultTo({}, queue[1])

return (
  <main className="screenWrapper">
    <div className="screenHeader">
      <span className="screenFirstUser">
        {(() => {
          if (person1.experiencelevel === 'novice') {
            //  light purple
            return (
              <div style={{color:'#BF5FFF', fontWeight: 'bold', display: 'inline-block'}}>{person1.firstname}</div>
            )
          } else if (person1.experiencelevel === 'beginner') {
            //   light blue
            return (
              <div style={{color:'#87CEFA', fontWeight: 'bold', display: 'inline-block'}}>{person1.firstname}</div>
            )
          } else if (person1.experiencelevel === 'intermediate') {
            return (
              <div style={{color:'orange', fontWeight: 'bold', display: 'inline-block'}}>{person1.firstname}</div>
            )
          } else if (person1.experiencelevel === 'advanced') {
            //  gym green
            return (
              <div style={{color:'#93C90E', fontWeight: 'bold', display: 'inline-block'}}>{person1.firstname}</div>
            )
          }else if (person1.experiencelevel === 'expert') {
            return (
              <div style={{color:'red', fontWeight: 'bold', display: 'inline-block'}}>{person1.firstname}</div>
            )
          }
        })()}
      </span>
      <span className={`screenTimer alt ${rest ? 'rest' : ''}`}>{time ? time : '0:00'}</span>
      <span className="screenSecondUser">
      {(() => {
          if (person2.experiencelevel === 'novice') {
            //    light purple
            return (
              <div style={{color:'#BF5FFF', fontWeight: 'bold', display: 'inline-block'}}>{person2.firstname}</div>
            )
          } else if (person2.experiencelevel === 'beginner') {
            //  light blue
            return (
              <div style={{color:'#87CEFA', fontWeight: 'bold', display: 'inline-block'}}>{person2.firstname}</div>
            )
          } else if (person2.experiencelevel === 'intermediate') {
            return (
              <div style={{color:'orange', fontWeight: 'bold', display: 'inline-block'}}>{person2.firstname}</div>
            )
          } else if (person2.experiencelevel === 'advanced') {
            //   gym green
            return (
              <div style={{color:'#93C90E', fontWeight: 'bold', display: 'inline-block'}}>{person2.firstname}</div>
            )
          }else if (person2.experiencelevel === 'expert') {
            return (
              <div style={{color:'red', fontWeight: 'bold', display: 'inline-block'}}>{person2.firstname}</div>
            )
          }
        })()}
      </span>
    </div>
    <p className="screenVariation">{variation.title}</p>
    <div className="screenMoves">
      {this.renderMovement(workout.movementOne, workout.equipmentOne)}
      {this.renderMovement(workout.movementTwo, workout.equipmentTwo)}
      {this.renderMovement(workout.movementThree, workout.equipmentThree)}
        </div>
      </main>
    )
  }
}

export default Screen

New to node and react. Appreciate the guidance!
Edited with updated code.


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.