Can't perform a React state update on an unmounted component, I tried to fix it but it still renders the same problem - node.js

Hi there I am using Chart.js to create a doughnut chart, but I see to get "Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function." I will show my front end and back end that are relevant to the question. Also the server side fetches everything correctly and it also console logs it perfectly in the front end the way I need it to.
results. js basically the server side
router.get("/occ", authorization, async (req, res) => {
try {
console.log(req);
const result = await pool.query(
// "SELECT occupation,COUNT(occupation) FROM resources GROUP BY occupation;",
"SELECT occupation,COUNT(occupation) as values FROM resources GROUP BY occupation"
);
console.log(req);
console.log(result);
res.status(200).json({
status: "success",
data: {
occupationResults: result.rows, //this gets the one row we need
},
});
} catch (err) {
console.error(err.message);
}
});
DoughnutChart.js the component itself
import React, { Fragment, useState, useEffect } from "react";
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js";
import { Doughnut } from "react-chartjs-2";
ChartJS.register(ArcElement, Tooltip, Legend);
const DoughnutChart = () => {
// const [user_id, setuserid] = useState("");
const [results, setResults] = useState([]);
async function getResults() {
try {
const response = await fetch(`http://localhost:4001/results/occ`, {
method: "GET",
//pass token with localstorage because it is stored in the header
headers: { token: localStorage.token },
});
const parseRes = await response.json();
// setpersonalForm(parseData);
console.log(parseRes);
// setUsername(parseRes.username);
setResults(parseRes.data.occupationResults);
// setuserid(parseRes.user_id); //
// const encryptStorage = new EncryptStorage('secret-key');
// removed the localstorage user id
console.log(parseRes.data.occupationResults);
} catch (err) {
console.error(err.message);
}
}
var data = {
labels: results?.map((x) => x.occupation),
datasets: [
{
label: `${results?.length} Amount per Occupation`,
data: results?.map((x) => x.values),
backgroundColor: [
"rgba(255, 99, 132, 0.2)",
"rgba(54, 162, 235, 0.2)",
"rgba(255, 206, 86, 0.2)",
"rgba(75, 192, 192, 0.2)",
"rgba(153, 102, 255, 0.2)",
"rgba(255, 159, 64, 0.2)",
],
borderColor: [
"rgba(255, 99, 132, 1)",
"rgba(54, 162, 235, 1)",
"rgba(255, 206, 86, 1)",
"rgba(75, 192, 192, 1)",
"rgba(153, 102, 255, 1)",
"rgba(255, 159, 64, 1)",
],
borderWidth: 1,
},
],
};
var options = {
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
},
},
legend: {
labels: {
fontSize: 26,
},
},
};
//going to make a request when we get to this component, this is for getting from database
useEffect(() => {
getResults();
return () => {
setResults({}); // I added this but it still doesn't work
};
}, []);
return (
<div>
<Doughnut data={data} options={options} height={400} />
</div>
);
};
export default DoughnutChart;
Where I am importing the component.
import React, { Fragment, useState, useEffect } from "react";
import DoughnutChart from "./DoughnutChart";
//import { toast } from "react-toastify";
import "./pagecss/home.css";
// import { FontAwesomeIcon } from "#fontawesome-free-solid";
// import { encryptStorage } from "./encrypt";
const Home = ({ setAuth }) => {
const [username, setUsername] = useState("");
const [user_id, setuserid] = useState("");
// const [personalForm, setpersonalForm] = useState([]);//
// const [Pform, setform] = useState(false);
async function getUsername() {
try {
const response = await fetch("http://localhost:4001/home/", {
method: "GET",
//pass token with localstorage because it is stored in the header
headers: { token: localStorage.token },
});
const parseRes = await response.json();
// setpersonalForm(parseData);
setUsername(parseRes.username);
setuserid(parseRes.user_id); //
// const encryptStorage = new EncryptStorage('secret-key');
// encryptStorage.setItem("user_id", parseRes.user_id);
console.log(parseRes);
} catch (err) {
console.error(err.message);
}
}
//going to make a request when we get to this component, this is for getting from database
useEffect(() => {
getUsername();
}, []);
return (
<Fragment>
<div className="container">
<div className="row">
<div className="col-md-4 col-sm-12 d-flex justify-content-center">
<div className="card-body text-center text-white">
<i className="fa-solid fa-bullseye fa-6x my-3 "></i>
<h2 className="card-title mb-4">Card Title</h2>
<p className="card-text">
Our Mission is to help the community out by helping people with
mental health issues
</p>
</div>
</div>
<div className="col-md-4 col-sm-12 d-flex justify-content-center">
<div className="card-body text-center text-white">
<i className="fa-solid fa-glasses fa-6x text-center my-3 "></i>
<h2 className="card-title mb-4">Card Title</h2>
<p className="card-text">
Our Mission is to help the community out by helping people with
mental health issues
</p>
</div>
</div>
<div className="col-md-4 col-sm-12 d-flex justify-content-center">
<div className="card-body text-center text-white pb-4">
<i className="fa-solid fa-hand-holding-medical fa-6x text-center my-3 "></i>
<h2 className="card-title mb-4">Card Title</h2>
<p className="card-text">
Our Mission is to help the community out by helping people with
mental health issues
</p>
</div>
</div>
</div>
</div>
<div className="container-fluid">
<div className="row justify-content-around">
<div
className="card col-lg-5 col-md-6 col-sm-12 d-flex justify-content-center mb-5 "
id="CardOne"
>
<img
src={require("./pictures/ProPic.jpg")}
className="card-img-top"
id="pictureOne"
alt="..."
/>
<div className="card-body text-center text-black">
<h2 className="card-title mb-4">Alexey Aulov</h2>
<p className="card-text">
Hi my name is Alexey Aulov I am a senior at College of Staten
Island studying Information System and Informatics. I had the
original idea of Essential Health after I witnessed that
sometimes the best way for people to get mental help is to have
Therapist that can relate to you as much as possible to help you
out. Helping people gives me the most gratitude in life.
</p>
</div>
</div>
<div
className="card col-lg-5 col-md-6 col-sm-12 d-flex justify-content-center mb-5 "
id="CardTwo"
>
<img
src={require("./pictures/ProPic.jpg")}
className="card-img-top"
alt="..."
id="pictureTwo"
/>
<div className="card-body text-center text-black">
<h2 className="card-title mb-4">Card Title</h2>
<p className="card-text">
Our Mission is to help the community out by helping people with
mental health issues
</p>
</div>
</div>
</div>
<DoughnutChart />
</div>
</Fragment>
);
};
export default Home;

Related

Pass a valid time type usnig moment from React setState to postgres

I am new in coding and essentially in React. I am trying to create a human resource management system that will have an employee and an admin. I am now working on using an axios to post to knex postgres as db and nodejs.
I need help to pass in a correct value with format of "HH:mm:ss" to my backend taking time type.
This is my knex migration:
exports.up = function(knex) {
return knex.schema.createTable('undertime_overtime', (table) => {
table.increments('id').primary();
table.date('date_filed').notNullable(); //has to be default date now?
table.time('from_time').notNullable();
table.time('to_time').notNullable();
table.string('reason').notNullable();
table.integer('time_type').defaultTo(1);
table.boolean('isDeleted').defaultTo(0);
table.boolean('isAccepted').defaultTo(0);
table.timestamp('created_at').defaultTo(knex.fn.now());
table.timestamp('modified_at').defaultTo(null);
table.integer('created_by').unsigned().notNullable();
table.foreign('created_by').references('employees.id');
});
Here are the things I tried that did not work:
state = {
date_filed: new Date(),
from_time: moment().format("HH:mm:ss").toString(),
to_time: moment().format("HH:mm:ss"),
reason: '',
time_type: 1,
created_by: 1 //todo
};
handleFromTime = time => {
this.setState({
from_time: time.format("HH:mm:ss")
});
console.log(time("HH:mm:ss"));
};
Here is my component:
import React, { Component } from 'react';
import moment from 'moment';
import { Content, Row, Col, Box, Button } from 'adminlte-2-react';
import TimePicker from 'rc-time-picker';
import DatePicker from "react-datepicker";
import axios from 'axios'
import 'rc-time-picker/assets/index.css';
class OvertimeComponent extends Component {
state = {
date_filed: new Date(),
from_time: moment(),
to_time: moment(),
reason: '',
time_type: 1,
created_by: 1 //todo
};
handleChangeDateFiled = date => {
this.setState({
date_filed: date
});
console.log(date)
};
handleFromTime = time => {
this.setState({
from_time: time
});
console.log(time);
};
handleToTime = time => {
this.setState({
to_time: time
});
console.log(time.format('HH:mm:ss'));
};
handleReason = event => {
this.setState({
reason: event.target.value
})
console.log(event.target.value);
}
handleSubmit = event => {
console.log(`date-> ${this.state.date_filed} from ${this.state.from_time} to ${this.state.to_time} reason ${this.state.reason}`)
event.preventDefault()
axios.post('http://localhost:8080/api/time',this.state)
.then(response=> {
console.log(response);
}).catch(error => {
console.error(error);
})
}
footer = [
<Button key="btnSubmit" type="success" pullRight text="Submit" onClick={this.handleSubmit} />,
];
render() {
return (
<Content title="Overtime" subTitle="Requests" browserTitle="Overtime">
<Row>
<Col md={6}>
<Row>
<Col xs={12}>
<Box title="Overtime Application" type="primary" collapsable footer={this.footer}>
<div className="form-group">
<label>Date</label>
<div>
<DatePicker name="date_filed" selected={this.state.date_filed} onChange={this.handleChangeDateFiled}/>
</div>
</div>
<div className="form-group">
<label>From</label>
<div>
<TimePicker name="from_time" value={this.state.from_time} onChange={this.handleFromTime} />
</div>
</div>
<div className="form-group">
<label>To</label>
<div>
<TimePicker name="to_time" value={this.state.to_time} onChange={this.handleToTime} />
</div>
</div>
<div className="form-group">
<label>Reason</label>
<textarea type="text" name="reason" value={this.state.reason} onChange={this.handleReason} className="form-control" placeholder="Enter ..." />
</div>
</Box>
</Col>
</Row>
</Col>
<Col md={6}>
<Box title="Request Status" type="primary" collapsable>
<div className="form-group">
<label>todo</label>
</div>
</Box>
</Col>
</Row>
</Content>);
}
}
export default OvertimeComponent;
I found the issue. I should've touched the axios post to get the format I wanted from the moment object.
axios.post('http://localhost:8080/api/time',{
'date_filed':this.state.date_filed,
'from_time':this.state.from_time.format('HH:mm:ss'),
'to_time':this.state.to_time.format('HH:mm:ss'),
'reason':this.state.reason,
'created_by': 1 //todo
})

How do i auto-refresh my log rather then refreshing it manually

I currently have a log box which shows the log from my backend. I have a button to refresh the log and the latest set of logs shows up. How do I set it to a auto-refresh log?
I have the code below for the button and switchbox
<div class="form-group row m-b-10">
<label class="col-form-label">Auto-Refresh:</label>
<div class="col-md">
<div class="switcher switcher-success">
<input type="checkbox" v-model="checked" name="switcher_checkbox_2" id="switcher_checkbox_2" checked="true" value="1" v-on:change="toggle">
<label for="switcher_checkbox_2"></label>
</div>
<div class="switcher switcher-success">
<button v-if="!checked" #click="logNode(namespace)" class="btn btn-xs btn-success">Refresh</button>
</div>
</div>
And the function for the refresh button is below. How do I call a function for the log to load on auto refresh when the switchbox is on?
logNode(namespace) {
console.log(namespace)
this.hidemodal = true;
this.logShow = true;
var requestobj = {
Namespace: namespace,
};
var apiobj = {
tablename: "bnm",
Id: VueCookies.get("activeNetwork_Id"),
method: "post"
};
var obj = {
apiobj: apiobj,
mainobj: requestobj
};
this.$store
.dispatch("logsAPI", obj)
.then(response => {
console.log(response);
console.log("test result");
if (response.data || response.status == 200) {
this.logString = response.data.Logstr;
this.$notify({
group: "querynotify",
title: "Success",
type: "success",
position: "top-right",
text: "Sucessfully Created Logs " + ":\n" + response.data.Username
});
} else {
this.$notify({
group: "querynotify",
title: "Error",
type: "warn",
position: "top-right",
text: "Error Creating Logs " + ":\n" + response.data.Username
});
}
})
.catch(error => {
this.$notify({
group: "querynotify",
title: "Error",
type: "error",
position: "top-right",
text: "Error View this node Log" +
":\n" +
error.data.err +
":\n" +
error.data.details
});
});
},
When you check box is checked, you can use setInterval() and when your checkbox is unchecked clearInterval.
Please check below working snippet.
*Note in this snippet, I have just used simple log for demo purpose. In that demo you can put your logic.
new Vue({
el: '#app',
data: {
checked: false,
autoRef:null
},
methods: {
toggle() {
if(this.checked){
this.autoRef = setInterval(() => {
this.logNode('Auto refresh called');
}, 3000);
}else{
clearInterval(this.autoRef);
}
},
logNode(msg) {
console.log(msg)
}
}
});
.btn-success {
background: green;
padding: 10px;
border: 1px solid #ccc;
color: #fff;
}
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.2.2/dist/vuetify.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.2.2/dist/vuetify.min.js"></script>
<div id="app" class="form-group row m-b-10">
<label class="col-form-label">Auto-Refresh:</label>
<div class="col-md">
<div class="switcher switcher-success">
<input type="checkbox" v-model="checked" name="switcher_checkbox_2" id="switcher_checkbox_2" checked="true" value="1" v-on:change="toggle">
<label for="switcher_checkbox_2"></label>
</div>
<div v-if="!checked" class="switcher switcher-success">
<button ref="myButton" #click="logNode('on button click')" class="btn btn-xs btn-success">Refresh</button>
</div>
</div>

PayloadTooLargeError: request entity too large when upload image

I am trying to upload/and save an image in base64 format to my mongo database.
If I use a very very small image it works, but I try to use an image of 161 kb, I have this error:
PayloadTooLargeError: request entity too large
So I try to convert my image with Json but I got an error or it doesn't work,
Her my code ( I am using vue):
<template>
<div class="profile">
<div class="px-4">
<div class="row justify-content-center">
<div class="col-lg-3 order-lg-2">
<div class="card-profile-image image-preview">
<div v-if="profImage !=undefined && profImage.length > 0">
<a>
<img
:src="profImage"
class="rounded-circle"
/>
</a>
</div>
<div>
<div class="file-upload-form">
Upload image:
<input
type="file"
#change="previewImage"
accept="image/*"
/>
</div>
<div class="image-preview" v-if="imageData.length > 0">
<img class="preview" :src="imageData" />
<button #click="updateUserImage"></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
Here my js file:
<script>
import DataService from '#/services/DataService'
export default {
name: 'Profile',
data: function() {
return {
username: '',
imageData: '',
profImage: '',
}
},
methods: {
previewImage: function(event) {
var input = event.target
if (input.files && input.files[0]) {
var reader = new FileReader()
reader.onload = e => {
this.imageData = e.target.result
}
reader.readAsDataURL(input.files[0])
}
},
async getAllInfo() {
var userImage = await DataService.getUserImage({
username: this.username
})
this.profImage = userInfo.data.user[0].profImage //IT Works
this.profImage = JSON.parse(userInfo.data.user[0].profImage) //I get an error
},
async updateUserImage() {
var temp = JSON.stringify(this.imageData)
console.log(this.firstname)
await DataService.updateUserInfo({
username: this.username,
user: {
profImage: temp
}
})
}
},
mounted() {}
}
</script>
When I try to use "JSON.parse(userInfo.data.user[0].profImage)"I get an error :
"Unexpected token d in JSON at position 0"
I also try with JSON.Stringify, but I get is not a function.
In my db, the image is saved in this way:
profImage: {
image: Buffer,
require: false
},
What am I doing wrong? I am using mongodb, vue , express and node.
I change the parser limit using
bodyParser.json({ limit: "50mb" })
and works for me

I am getting a Warning: A component is changing an uncontrolled input of type text to be controlled

I building a simple todo app using the MERN stack with router and able to get it going except the edit part. I have 3 routes, the "Todos" page where i use axios to get the data from my express server route. The "Add" page for create new todo and the "Edit" page for editing and deleting. Here's my todos page where each todo has a button that takes the id as a url parameter unto the Edit page.
That little pencil/paper icon on each todo is a button link that get's the ID on click. Here's my Edit page with the data.
The warning:
Here's my Todos page i'm using a custom hook to fetch the data from express server route:
import React from 'react';
import useGetAPI from '../custom_hooks/useGetAPI';
import Todo from './todo_item/Todo';
const Todos = () =>{
const data = useGetAPI('http://localhost:4000');
return (
<div className="page">
<div className="page-header">
<h1>Todo Lists</h1>
</div>
<div className="page-content">
<ul className="todo-list">
{
data.map((todo)=><Todo todo={todo} key={todo._id}/>)
}
</ul>
</div>
</div>
);
}
export default Todos;
Here's my custom hooks for fetching data - used in Todos.
import {useState,useEffect} from 'react';
import axios from 'axios';
const useGetAPI = (url)=>{
const [data,setData] = useState([]);
useEffect(()=>{
const fetchData = async ()=>{
const response = await axios.get(url);
const data = [...response.data];
const error = response.error;
if(error)
console.log(error)
else{
console.log(data);
setData(data);
}
};
fetchData();
},[url])
return data;
}
export default useGetAPI;
Here's my Edit Page
import React,{useState, useEffect, useContext, useCallback} from 'react';
import useGetApiWithParams from '../custom_hooks/useGetApiWithParams';
import {FaTelegramPlane} from 'react-icons/fa';
import axios from 'axios';
import { matchPath } from 'react-router'
const EditTodo = (props) =>{
const todoID = props.match.params.id;
const [todo,setTodo] = useState(null);
const responseData = useGetApiWithParams('http://localhost:4000/edit',todoID);
console.log(`Todo id: ${todoID}`);
/* Set default data from database */
useEffect(()=>{
setTodo(responseData);
},[responseData,setTodo]);
const [description,setDescription] = useState('');
const [responsible,setResponsible] = useState('');
const [priority,setPriority] = useState('');
const [completed,setCompleted] = useState(false);
const handleDescription = useCallback((e)=>{
setDescription(e.target.value);
},[setDescription]);
const handleResponsible = useCallback((e)=>{
setResponsible(e.target.value);
},[setResponsible]);
const handlePriority = useCallback((e)=>{
setPriority(e.target.value);
},[setPriority]);
const handleCompleted = useCallback((e)=>{
setCompleted(!completed);
},[completed,setCompleted])
const handleSubmit = useCallback((e)=>{
e.preventDefault();
console.log('Form submitted');
console.log(`Description ${description}`);
console.log(`Description ${responsible}`);
console.log(`Description ${priority}`);
console.log(`Description ${completed}`);
const updatedTodo = {
description,
responsible,
priority,
completed: false
}
axios.put(`http://localhost/4000/edit/${props.match.params.id}`, updatedTodo)
.then(res=>console.log(res.data))
.catch(function (error) {
console.log(error);
});
},[description,responsible,priority,completed,props.match.params.id]);
return (
<div className="page">
<div className="page-header">
<h1>Edit Todo</h1>
</div>
<div className="page-content">
<form id="edit-todo-form" className="todo-form" onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="description">Description:</label>
<input id="description" type="text" className="form-control" onChange={handleDescription} value={responseData.description} />
</div>
<div className="form-group">
<label htmlFor="responsible">Responsible:</label>
<input id="responsible" type="text" className="form-control" onChange={handleResponsible} value={responseData.responsible} />
</div>
<div className="form-group">
<label htmlFor="priorities">Priorities:</label>
<div id="priorities" className="form-radios">
<label htmlFor="radio1" className="radio-label">
<input name="priorityOptions" type="radio" id="radio1" value={responseData.priority} checked={priority === 'Low'} onChange={handlePriority}/>
<span className="radiomark"></span>
<span className="radiotext">Low</span>
</label>
<label htmlFor="radio2" className="radio-label">
<input type="radio" id="radio2" value={responseData.priority} checked={priority === 'Medium'} onChange={handlePriority}/>
<span className="radiomark"></span>
<span className="radiotext">Medium</span>
</label>
<label htmlFor="radio3" className="radio-label">
<input type="radio" id="radio3" value={responseData.priority} checked={priority === 'High'} onChange={handlePriority}/>
<span className="radiomark"></span>
<span className="radiotext">High</span>
</label>
</div>
</div>
<div className="form-group">
<label htmlFor="todo_completed">Status:</label>
<div id="todo_completed">
<label htmlFor="checkcompleted" className="check-label">
<input type="checkbox" id="checkcompleted" value={responseData.completed} onChange={handleCompleted}/>
<span className="checkmark"></span>
<span className="checktext">Completed</span>
</label>
</div>
</div>
<div className="form-group">
<button type="submit" className="form-btn"><FaTelegramPlane />Save Changes</button>
</div>
</form>
</div>
</div>
);
}
export default EditTodo;
Here's my custom hook for fetching data based on the Todo ID i get from the url:
import { useState,useEffect } from 'react';
import axios from 'axios';
const useGetApiWithParams = (url,params)=>{
const [data,setData] = useState([]);
useEffect(()=>{
const fetchData = async ()=>{
const response = await axios.get(`${url}/${params}`);
const data = response.data;
const error = response.error;
if(error)
console.log(`Error: ${error}`)
else{
console.log(...data);
setData(...data);
}
};
fetchData();
},[url,params])
return data;
}
export default useGetApiWithParams;
And the url with id param from MongoDB:
How to solve this? I tried the placeholder and set it's value to the response data from api but it only works for text boxes, what about the radio buttons and checkboxes? They don't seem to set the default value. For example the radio button for setting the priority value={responseData.priority} doesn't set the value as you can see here:
What i would like to happen is: from the Todos page on clicking the edit button, the edit page with a form already filled with values based on the todo id from the url parameter and be able to edit the values as well. Need help, thanks!

I've implemented a video tag inside of a modal. On click of it the video should play. But, in my case, the same video is playing

I'm new to React and trying to create a video library. Everything is working fine but I'm not not able to render the video in a dynamic way. Even if what I have implemented is dynamic, but it's playing the same video.
server.js
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const app = express();
const port = process.env.PORT || 5000;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.get('/latestVideos', (req, res) => {
res.send({
"videos": [
{
"thumbnail":"https://i.ytimg.com/vi/R-9i5NJsiL0/maxresdefault.jpg",
"source": "http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-85.mp4",
"title": "Lambhorghini",
"channelName":"Auto Car",
"views":"7 million views",
"lastUpdated":"3 weeks ago"
},
{
"thumbnail":"https://theawesomer.com/photos/2016/09/n6pdwdmjkze.jpg",
"source": "http://yt-dash-mse-test.commondatastorage.googleapis.com/media/motion-20120802-85.mp4",
"title": "Porche",
"channelName":"LoudWire",
"views":"1 million views",
"lastUpdated":"4 weeks ago"
},
{
"thumbnail":"https://i.ytimg.com/vi/bsSK1DccV_Y/maxresdefault.jpg",
"source": "http://yt-dash-mse-test.commondatastorage.googleapis.com/media/oops-20120802-85.mp4",
"title": "Havana",
"channelName":"Camila Cabello",
"views":"7 million views",
"lastUpdated":"6 weeks ago"
},
{
"thumbnail":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS6njcfy1wTsPr8WAs5CubtCommlw2HAfYFIp1IY2yWRU2Oj1uM4A",
"source": "http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-85.mp4",
"title": "See You Again",
"channelName":"Charlie Puth",
"views":"3 million views",
"lastUpdated":"1 week ago"
},
{
"thumbnail":"https://i.ytimg.com/vi/Z0P9KW9B7nw/maxresdefault.jpg",
"source": "http://yt-dash-mse-test.commondatastorage.googleapis.com/media/motion-20120802-85.mp4",
"title": "Manali To Leh",
"channelName":"Mumbiker Nikhil",
"views":"5 million views",
"lastUpdated":"2 weeks ago"
},
{
"thumbnail":"https://mm.aiircdn.com/5/679578.jpg",
"source": "http://yt-dash-mse-test.commondatastorage.googleapis.com/media/oops-20120802-85.mp4",
"title": "Don't Talk To Strangers",
"channelName":"Ronnie James Dio",
"views":"1 million views",
"lastUpdated":"4 weeks ago"
}
]
});
});
app.listen(port, () => console.log(`Listening on port ${port}`));
latestVideos.js
import React, { Component } from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {latestVideos} from "../../actions";
class LatestVideos extends Component {
componentWillMount() {
this.props.getLatestVideos();
}
render() {
const {latestVideos} = this.props;
return (
<div className="container">
<h4 className="mt-3 mb-3"><i className="fas fa-play mr-2"></i>Latest Videos</h4>
<div className="row">
{latestVideos && latestVideos.map((data, i) => {
return (
<div key={i} className="col-sm-4">
<div className="card mb-3">
<img className="card-img-top" data-toggle="modal" data-target="#myModal" src={data.thumbnail}></img>
<div className="modal fade" id="myModal">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-body">
<video src={data.source} id="video"
poster="//shaka-player-demo.appspot.com/assets/poster.jpg"
controls muted autoPlay>
</video>
{console.log(data.s)}
</div>
</div>
</div>
</div>
<div className="card-body">
<h5 className="card-title">{data.title}</h5>
<p className="card-text">{data.channelName}</p>
<p>{data.views} | {data.lastUpdated}</p>
</div>
</div>
</div>
)
})}
</div>
</div>
)
}
}
const mapStateToProps = state => {
return {
latestVideos: state.videoBrowseList.latestVideos,
}
};
const mapActionsToProps = dispatch => {
return bindActionCreators({
getLatestVideos: latestVideos
}, dispatch);
};
export default connect(mapStateToProps, mapActionsToProps)(LatestVideos);
As you can from my code that is in server.js, everything is dynamic and in the frontend I have used map function. Everything is rendering, only the video, is playing the same video over and over again. Can someone please help me to troubleshoot this error
This is because your id myModal is same for all modal window, so only the first modal will be opened always, id should be unique.
Try the below code
<img className="card-img-top" data-toggle="modal" data-target={"#myModal" + i} src={data.thumbnail}></img>
<div className="modal fade" id={"myModal" + i}>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-body">
<video src={data.source} id={"video" + i} poster="//shaka-player-demo.appspot.com/assets/poster.jpg"
controls muted autoPlay>
</video>
{console.log(data.s)}
</div>
</div>
</div>
</div>

Resources