Stream the contents of each file using web sockets and ReactJs - javascript

I am trying to read files of a directory and usin socket i have to render the file name and file data using React.
here is what i have done:
Server :
var files = fs.readdirSync(currentPath);
for (var i in files) {
(function(j){
var currentFile = currentPath + '/' + files[j];
var fileName = files[j];
var stats = fs.statSync(currentFile);
if (stats.isFile()) {
fs.readFile(currentFile, function (err, data) {
if (err)
throw err;
if (data){
var fileAndData=currentFile+" "+data.toString('utf8')
io.emit('file data',fileAndData);
console.log("file name and file data ***",currentFile+data.toString('utf8'));
}
});
}
else if (stats.isDirectory()) {
traverseFileSystem(currentFile);
}
}
)( i );
}
client :
parent component :
class FileData extends Component{
constructor(props) {
super(props);
this.state = {
filedata:null,
filename:null,
data:[]
}
}
componentDidMount() {
socket.on('file data', function(msg){
this.state.data.push(msg);
// this.setState({filename:msg})
}.bind(this));
}
render(){
return(<div>
<DataCard data={this.state.data}/>
</div>);
}
}
ReactDOM.render(
<FileData/>,document.getElementById('messages')
);
client : child component
constructor(props) {
super(props);
this.state={data:this.props.data}
}
render(){
console.log("array",Array.isArray(this.state.data))
console.log("array length",this.state.data.length)
console.log("array is ==>",this.state.data)
return(
<MuiThemeProvider>
</MuiThemeProvider>);
}
I want display the data and file name and file data using map.But when i am consoling the data recieved in child component Array length is Zero. Here is the
console result :
array true
array length 0
array is ==> Array[0]0: "/vagrant/assignment/server/data//file 1.txt hello from file 1."1: "/vagrant/assignment/server/data//file 2.txt hello from file 2."length: 2__proto__: Array[0]
Why 3rd console showing 2 data if its length is zero.

You can't mutate the state by doing this.state.data.push(msg);
Try
var data = this.state.data;
data.push(msg);
this.setState({data: data});

Related

Load an array with react.js

I have a problem with the react.js code below, the services performs the loading of an array of values ​​what interests me at this moment is the first value of the array inside the component, if I display the first CodArt value before configuring the setState (so if I view the console.log) the value is printed when I view it through the setState tells me that it is not set.
Services.js :
const axios = require('axios').default;
export async function caricamentoarticoliutilizzati() {
var listaarticoli=[];
await axios.post(server.url+'/articolo/statistiche', {})
.then(function (response) {
let data = response.data;
for (let index in data){
var datatemp={
CodMarca : data[index].CodMarca,
CodArt : data[index].CodArt,
Totale : data[index].Totale
};
listaarticoli.push(datatemp);
}
}).catch(function (error) {
console.log("Errore: "+error);
});
return listaarticoli;
}
Main.js:
class Dashboard extends React.Component {
constructor(props) {
super(props);
this.state = {
graph: null,
checkedArr: [false, false, false],
totalePreventiviInseriti: 0,
percentualeAccettati:0,
percentualeRifutati:0,
percentualeInCorso:0,
percentualeCantieriChiusi:0,
percentualeCantieriInCorso:0,
percentualeCantieriContoInviato:0,
percentualeCantieriBolle:0,
articoliUtilizzati:[],
};
this.checkTable = this.checkTable.bind(this);
}
async componentDidMount() {
var totalePreventiviInseriti= await getStatistichePreventivi();
var percentualeAccettati=await getStatistichePreventiviAccettati();
var percentualeRifutati=await getStatistichePreventiviRifiutati();
var percentualeInCorso=await getStatistichePreventiviInCorso();
var cantieriPercentualiChiusi=await getStatisticheCantieri("Chiuso");
var cantieriPercentualiInCorso=await getStatisticheCantieri("InCorso");
var percentualeCantieriContoInviato=await getStatisticheCantieri("Conto Inviato");
var percentualeCantieriBolle=await getStatisticheCantieri("Lavoro terminato inserire bolle ");
var articoliUtilizzati=await caricamentoarticoliutilizzati();
console.log("articoliUtilizzati: "+ articoliUtilizzati[0].CodArt.toString());
//Inserimento valori nello stato
this.setState({ totalePreventiviInseriti: totalePreventiviInseriti });
this.setState({ percentualeAccettati: percentualeAccettati });
this.setState({ percentualeRifutati: percentualeRifutati });
this.setState({percentualeInCorso: percentualeInCorso});
this.setState({percentualeCantieriChiusi: cantieriPercentualiChiusi});
this.setState({percentualeCantieriInCorso: cantieriPercentualiInCorso});
this.setState({percentualeCantieriContoInviato: percentualeCantieriContoInviato});
this.setState({percentualeCantieriBolle: percentualeCantieriBolle});
this.setState({articoliUtilizzati: articoliUtilizzati});
}
render(){
....
<p> this.state.articoliUtilizzati[0].CodArt //-->CodArt not set
}
that is because the call to caricamentoarticoliutilizzati return a promise not the array listaarticoli. so in componenetDidMount the variable articoliUtilizzati holds a promise object you can confirm this by:
var articoliUtilizzati=await caricamentoarticoliutilizzati();
console.log("articoliUtilizzati: "+ articoliUtilizzati.then(arr =>arr[0].CodArt.toString()));

How to get a data after react select using axios and ReactJS?

I am newbie on ReactJS, I want to get a Price value just after the select of the Product name by react select and display it.
My method :
constructor(props) {
super(props);
this.state = {
PrixV: ""
}
PrixDisplay(selectprdt) {
return axios.get("/app/getPrixprod/" + selectprdt).then(response => {
if (response && response.data) {
this.setState({
PrixV: response.data
});
}
console.log(response.data)
}).catch(error => {
console.error(error);
});
}
I try to read this value by :
<p>{this.state.PrixV} </p>
When I run it, nothing is displayd on the Price column and after I select the product name, I get :
Objects are not valid as a React child (found: object with keys {PrixV}). If you meant to render a collection of children, use an array instead.
in p (at AjouterFacture.js:383)
And the console returns :
[{…}]0: {PrixV: "250.000"}length: 1__proto__: Array(0)
How can I read and display it ?
You must use the map, try to change the code like this :
constructor(props) {
super(props);
this.state = {
Prix: []};
render() {
let {
Prix
} = this.state.Prix;
return (
<td>
{ this.state.Prix.map((pr, k) =>
<p key={k} >{pr.PrixV} </p>
)}
</td>
);}
PrixDisplay(selectprdt) {
return axios.get("/app/getPrixprod/" + selectprdt).then(response => {
if (response && response.data) {
this.setState({
Prix: response.data
});
}
}).catch(error => {
console.error(error);
});
}
I hope that's will be helpful.
constructor(props) {
super(props);
this.state = {
mydata: ''
};
productNameSelected(selectprdt) {//not sure from where you will get selectprdt variable , but something like this will work
axios.get("/app/getPrixprod/" + selectprdt).then(response => {
if (response && response.data) {
this.setState( {mydata : response.data});
}
console.log(response.data)
})
}
<p>{this.state.mydata} </p> //my data should not be a object , so you need to make string if you wnat to directly use it here
Edit
I can see you are able to get the response , but react still gives error:-
change the paragrah code to
<p>{this.state.PrixV[0].PrixV} </p>
Or The good way will be to set the data properly so
let paragrah be same
<p>{this.state.PrixV} </p>
PrixDisplay(selectprdt) {
return axios.get("/app/getPrixprod/" + selectprdt).then(response => {
if (response && response.data && response.data[0]) {
this.setState({
PrixV: response.data[0].PrixV
});
}
console.log(response.data)
}).catch(error => {
console.error(error);
});
}
You are getting the error because currently you are getting PrixV as an array(object) not a primitive data type.
Hope this solves the issue.

Signaling OpenTok and React

Has anyone implemented sending and receiving signals with opentok-react https://github.com/aiham/opentok-react? I can't find even a simple example on how to do it in React using opentok-react.
Thanks for using opentok-react. Unfortunately an easy way to do signaling hasn't yet been added to opentok-react so the following process is a bit convoluted.
To do signaling you will need to get access to the Session object and call the signal method on it as you normally would (See https://tokbox.com/developer/sdks/js/reference/Session.html#signal).
If you used the OTSession component you can access the Session object by getting a reference to the OTSession element (See https://reactjs.org/docs/refs-and-the-dom.html).
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.otSession = React.createRef();
}
render() {
return <OTSession ref={this.otSession} />;
}
}
and using its sessionHelper property to call the signal method:
this.otSession.current.sessionHelper.session.signal(...);
If you want to specify a particular target connection for the recipient then you need to get it from the underlying Publisher or Subscriber object's stream property. First get a reference to the OTPublisher or OTSubscriber element :
<OTPublisher ref={this.otPublisher} />
// or
<OTSubscriber ref={this.otSubscriber} />
Then get access to the Connection object:
this.otPublisher.current.getPublisher().stream.connection
// or
this.otSubscriber.current.getSubscriber().stream.connection
I have not tested this but once you have access to the Session and Connection objects then you can use the full signaling capabilities of the OpenTok JS SDK.
I Created a npm package 'opentok-rvc' with reference to opentok-react.
Here i created a listener to watch signaling and if any signal gets i send the signal to another event
// signal message listener inside npm package
session.on('signal:msg', function signalCallback(event) {
console.log(event);
onSignalRecieve(event);
});
Inside your component, please do the following
// to send the opentok signal
// here param data can be object for eg:
// data = { type: 'START_VIDEO_CALL', data: 'By Alex' }
onSignalSend = (data) => {
if (this.otSession.current !== null) {
this.otSession.current.sessionHelper.session.signal({
type: 'msg',
data: data
}, function signalCallback(error) {
if (error) {
console.log('onSignalSend Error', error)
} else {
console.log('onSignalSend Success', data)
}
})
}
}
// to receive the opentok signal
onSignalReceive = (signal) => {
console.log('onSignalReceive => ', JSON.parse(signal.data));
// based on signal data type you can do use switch or conditional statements
}
<OTSession
ref={this.otSession}
apiKey={apiKey}
sessionId={sessionId}
token={token}
onError={this.onSessionError}
eventHandlers={this.sessionEventHandlers}
onSignalRecieve={this.onSignalReceive}
getDevices={this.setDevices}
onMediaDevices={this.onMediaDevices}
checkScreenSharing={this.checkScreenSharing}>
<OTPublisher properties/>
<OTStreams>
<OTSubscriber properties/>
</OTStreams>
Here's a way to do this using functional component syntax.
import React, { useRef } from 'react';
import { OTSession, preloadScript } from 'opentok-react';
function MyComponent() {
const sessionRef = useRef();
const sendSignal = () => {
sessionRef.current.sessionHelper.session.signal(
{
type: 'TheSignalType',
data: 'TheData',
},
function (error) {
if (error) {
console.log('signal error: ' + error.message);
} else {
console.log('signal sent');
}
}
);
};
return (
<OTSession ref={sessionRef} apiKey={apiKey} sessionId={sessionId} token={token} eventHandlers={eventHandlers}>
// rest of your tokbox code here
<Button onClick={sendSignal}>Send Signal</Button>
</OTSession>
);
}
export default preloadScript(MyComponent);
In addition to #aiham answer, You can access the Opentok session Object getting the ref from the OTSession element and then send signals like below
otSession.current.sessionHelper.session.signal(
{
type: "msg",
data: text,
},
function(err, data) {
if (err) {
console.log(err.message);
} else {
console.log(data)
}
}
);
And signals can be received by adding a listener as follows;
otSession.current.sessionHelper.session.on("signal", (event) => {
console.log("i got", event);
});

Cant pass a function to a React child from parent (through a list)

Im trying to pass a simple list from a parent to a set of child components and i cant pass down a function. i have something line for line that is the exact same bloody thing that works but this does not.
Does anyone see what is going wrong?
This is the function in the parent that i cant reach (the console.log is not firing):
setClassImage(name, image){
console.log('inside setClassImage');
var TitleArray = this.state.TitleArray;
TitleArray[0] = name;
var ImageArray = this.state.ImageArray;
ImageArray[0] = image;
this.setState({
characterModal: false,
equipmentModal: false,
TitleArray: TitleArray,
ImageArray: ImageArray
});
}
Setting the list in the parent:
let listClasses;
if(this.state.classResults.length!=0){
listClasses = this.state.classResults.map((item,i) => {
return (
<ListClass key={i} classes={item} setClassImage={this.setClassImage.bind(this)}/>
);
});
}
in the render of the parent:
<SelectorBox>
<ListBox>
{listClasses}
<br/>
</ListBox>
<SelectorButton onClick={(e)=>this.cancelChange(e)}>No Class</SelectorButton>
</SelectorBox>
In the child:
class ListClass extends Component{
constructor(props){
super(props);
this.state={
}
}
getImage(e){
e.preventDefault();
var self = this;
axios.post('http://localhost:5000/post2/characterimage', {
search: this.props.classes,
})
.then((response)=>{
console.log('response from the pixabay call ', response.data);
self.props.setClassImage(self.props.classes, response.data);
})
.catch(()=>{
console.log('hello axios error');
});
}
render(){
return(
<div>
<ItemContainer onClick={(e)=>this.getImage(e)}>
<p>
{this.props.classes}
</p>
</ItemContainer>
</div>
)
}
}
I can see console.log('response from the pixabay call ', response.data); and it fires correctly from data on the backend. But the function is not called! The weirdly named containers are purely for styling, so just assume they all act like divs.
The arrow function in your .then() call will automatically bind this to the proper context, so you don't need to do the var self = this; However you do need to bind your getImage function in your constructor. OR
Update your function definition to:
....
getImage = (e) => {
e.preventDefault();
axios.post('http://localhost:5000/post2/characterimage', {
search: this.props.classes,
})
.then((response) => {
console.log('response from the pixabay call ', response.data);
this.props.setClassImage(this.props.classes, response.data);
})
.catch(()=>{
console.log('hello axios error');
});
}
....
}
Otherwise, bind getImage in your constructor:
constructor(props){
super(props);
this.state = {};
this.getImage = this.getImage.bind(this);
}

Getting Object: "undefined" on React

I am a newbie in react JS and I am trying to pull data from a url in Json format.
I did the following but I keep on getting a feeback at the console as
Rovers: undefined.
How do I go about it when am supposed to get something like
Rovers:[object, object, object]
class App extends React.Component {
constructor(props){
super(props);
this.state={rovers:[]};
}
componentWillMount(){
api.getRovers().then((response) =>{
this.setState({
rovers: response.rovers
});
});
}
render() {
console.log("Rovers: ", this.state.rovers);
}
and this is where am calling the json link
var api={
getRovers(){
var url='https://jsonplaceholder.typicode.com/posts/1';
return fetch(url).then((response)=> response.json());
}
};
module.exports=api;
The endpoint replies with object that does not include rovers. However, it includes : id, userId, title and body
That's why response.rovers is undefined. Then this.state.rovers is the same
So , you might mean body instead of rovers , in this case , replace:
componentWillMount(){
api.getRovers().then((response) =>{
this.setState({
rovers: response.rovers
});
});
}
By :
componentWillMount(){
api.getRovers().then((response) =>{
this.setState({
rovers: response.body.split('\n')
});
});
}

Categories