Not able to add chat message using Sockjs in react native - reactjs

I am facing issue in adding chat message in my Flatlist because I am not able to call any function inside stompClient.subscribe ()
My code is as following :
dummy='dummyurl';
sock = new SockJS(this.dummy);
componentDidMount() {
var that = this;
this.sock.onConnect =(e) =>{
console.log("connected")
}
this.sock.onopen = function() {
console.log('open');
var dummy2='dummyurl';
var sock2 = new SockJS(dummy2);
let stompClient = Stomp.over(sock2);
stompClient.heartbeat.outgoing = 20000;
stompClient.heartbeat.incoming = 0;
stompClient.connect({}, (frame) => {
stompClient.subscribe('xyz/getChat', (messageOutput) =>{
var mymessage =JSON.parse(messageOutput.body).message;
this.state = {
incomingchatMessage: "",
chatMessages:[]
}
that.setState({incomingchatMessage:mymessage}) //getting issue setState not found
console.log(this.state)
});
});
};
this.sock.onmessage =(e) =>{
console.log('message', e);
alert("on message calledj")
};
this.sock.onmessage = evt => {
console.log("erve");
}
}
In this code I am able to get net message inside new_message variable but not able to update state value here .
Any solution of this condition .

Related

SpringBoot + WebFlux + Reactjs Server Sent Events onmessage not fire up

I see EventStream on the network, but my clientSource.onmessage does not fireup on the client. I didn't find many examples in which they would use WebFlux Functional Endpoints for SSE. What am I doing wrong?
Router where /sseget is my SSE endpoint:
#Component
class PersonRouter {
#Bean
fun personRoutes(personRouteHandler: PersonRouteHandler) = coRouter {
"/person".nest {
GET("/", personRouteHandler::getTest)
// GET("findById", accept(MediaType.APPLICATION_JSON), personRouteHandler::)
GET("paramstest", accept(MediaType.APPLICATION_JSON), personRouteHandler::paramsTest)
POST("posttest", accept(MediaType.APPLICATION_JSON), personRouteHandler::postTest)
}
"/sse".nest {
GET("/sseget", personRouteHandler::sseGet)
}
}
}
Handler:
suspend fun sseGet(request: ServerRequest): ServerResponse {
val result = Flux.interval(Duration.ofSeconds(3))
.map{
ServerSentEvent.builder<String>()
.id(it.toString())
.event("periodic-event")
.data("SSE - " + LocalTime.now())
.comment("nejaky comment")
.retry(Duration.ofSeconds(10))
.build()
}
return ServerResponse
.ok()
.body(BodyInserters.fromServerSentEvents(result)).awaitSingle()
}
ReactJs client:
const ServerSideEventExample: React.FC<IProps> = (props) => {
const [listening, setListening] = useState(false);
useEffect(() => {
let eventSource: EventSource | undefined = undefined;
debugger;
if (!listening) {
debugger;
eventSource = new EventSource("http://localhost:8085/sse/sseget");
eventSource.onopen = (event) => {
debugger;
console.log(event);
};
eventSource.onmessage = (event) => {
debugger;
console.log(event);
};
eventSource.onerror = (err) => {
debugger;
console.error("EventSource failed:", err);
};
setListening(true);
}
return () => {
if (eventSource) {
eventSource.close();
console.log("event closed");
}
};
}, []);
return <div>a</div>;
};
Just put produce(MediaType.TEXT_EVENT_STREAM_VALUE) Your react application can't recognize your event.
Add the content-type to your server response as show below:
return ServerResponse
.ok()
.contentType(MediaType.TEXT_EVENT_STREAM)
.body(BodyInserters.fromServerSentEvents(result)).awaitSingle()
And remember to change the event parameter to "message" as follows
.id("Your ID")
.event("message") //<=== HERE
.data({your event here})
.comment("any comment")
.build();

React State is not updated with socket.io

When page loaded first time, I need to get all information, that is why I am calling a fetch request and set results into State [singleCall function doing that work]
Along with that, I am connecting websocket using socket.io and listening to two events (odds_insert_one_two, odds_update_one_two), When I got notify event, I have to
check with previous state and modify some content and update the state without calling again fetch request. But that previous state is still [] (Initial).
How to get that updated state?
Snipptes
const [leagues, setLeagues] = useState([]);
const singleCall = (page = 1, params=null) => {
let path = `${apiPath.getLeaguesMatches}`;
Helper.getData({path, page, params, session}).then(response => {
if(response) {
setLeagues(response.results);
} else {
toast("Something went wrong, please try again");
}
}).catch(err => {
console.log(err);
})
};
const updateData = (record) => {
for(const data of record) {
var {matchId, pivotType, rateOver, rateUnder, rateEqual} = data;
const old_leagues = [...leagues]; // [] becuase of initial state value, that is not updated
const obj_index = old_leagues.findIndex(x => x.match_id == matchId);
if(obj_index > -1) {
old_leagues[obj_index] = { ...old_leagues[obj_index], pivotType, rateOver: rateOver, rateUnder:rateUnder, rateEqual:rateEqual};
setLeagues(old_leagues);
}
}
}
useEffect(() => {
singleCall();
var socket = io.connect('http://localhost:3001', {transports: ['websocket']});
socket.on('connect', () => {
console.log('socket connected:', socket.connected);
});
socket.on('odds_insert_one_two', function (record) {
updateData(record);
});
socket.on('odds_update_one_two', function (record) {
updateData(record);
});
socket.emit('get_odds_one_two');
socket.on('disconnect', function () {
console.log('socket disconnected, reconnecting...');
socket.emit('get_odds_one_two');
});
return () => {
console.log('websocket unmounting!!!!!');
socket.off();
socket.disconnect();
};
}, []);
The useEffect hook is created with an empty dependency array so that it only gets called once, at the initialization stage. Therefore, if league state is updated, its value will never be visible in the updateData() func.
What you can do is assign the league value to a ref, and create a new hook, which will be updated each time.
const leaguesRef = React.useRef(leagues);
React.useEffect(() => {
leaguesRef.current = leagues;
});
Update leagues to leaguesRef.current instead.
const updateData = (record) => {
for(const data of record) {
var {matchId, pivotType, rateOver, rateUnder, rateEqual} = data;
const old_leagues = [...leaguesRef.current]; // [] becuase of initial state value, that is not updated
const obj_index = old_leagues.findIndex(x => x.match_id == matchId);
if(obj_index > -1) {
old_leagues[obj_index] = { ...old_leagues[obj_index], pivotType, rateOver:
rateOver, rateUnder:rateUnder, rateEqual:rateEqual};
setLeagues(old_leagues);
}
}
}

How to display the React Axios progress bar?

I want the result screen
My componentDidMount ()
_isMounted = false;
componentDidMount() {
this._isMounted = true;
var page = 0; // 공정 라인 수
//비가동 현황 불러오기
let oprationStatus = () => {
axios.get('http://localhost:8080/api/process/FM')
.then(response => {
var output = response && response.data;
//비가동 현황
NonOperationalStatus.data.series[0][0] = output.list[page].nop_000; // 계획
NonOperationalStatus.data.series[0][1] = output.list[page].nop_001; // 재료
NonOperationalStatus.data.series[0][2] = output.list[page].nop_002; // 금형
NonOperationalStatus.data.series[0][3] = output.list[page].nop_003; // 설비
NonOperationalStatus.data.series[0][4] = output.list[page].nop_004; // 사람
NonOperationalStatus.data.series[0][5] = output.list[page].nop_etc; // 기타
});
}
//가동율 등등 기본 정보 가져오기
let getProcess = () => {
oprationStatus();
axios.get('http://localhost:8080/api/process/FM')
.then(response => {
var output = response && response.data;
if(this._isMounted) {
this.setState({
data: output.list[page]
})
if(page < output.list.length-1) {
page++;
} else if(page == output.list.length-1) {
page = 0;
this.props.history.push('/hdprocess')
}
setTimeout(getProcess, 1000 * 5); // 매 5초마다 값 가져옴
}
});
}
getProcess();
}
componentWillUnmount() {
this._isMounted = false;
}
This code gets the data from the API server at 5 second intervals and routes it to the next page.
What I want is to display a progress icon as the picture above while the asynchronous communication is loading.
Let me know if you have a good alternative
Initially use a progress or spinner component.
Use it until a valid Response is return from the Axios Function, if a valid Response is attained, change the spinner(progres bar) Component to the actual component

how to update state with in method in reactjs

There is a state and i want to update this state with in a function.
In function i declared a variable and i want to update state with this variable.
this.state = {
RequestData : [],
searchopen : false,
capturedImage : ""
}
screenShot = () => {
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
// Get base64URL
var base64URL = canvas.toDataURL('image/jpeg').replace('image/jpeg', 'image/octet-stream');
});
this.setState({capturedImage: base64URL})
}
You need to put setState in function that get base64URL and bind your screenShot function to use this.setState:
// constructor
constructor(props) {
super(props);
this.state = {
RequestData: [],
searchopen: false,
capturedImage: ""
}
this.screenShot = this.screenShot.bind(this);
}
screenShot = () => {
html2canvas(document.body).then(function (canvas) {
document.body.appendChild(canvas);
// Get base64URL
var base64URL = canvas.toDataURL('image/jpeg').replace('image/jpeg', 'image/octet-stream');
this.setState({ capturedImage: base64URL })
}.bind(this)); // bind here also
}
The problem here is you are doing the state update outside the callback function. Since this is a asynchronous task, your method will not work. Try this:
screenShot = () => {
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
// Get base64URL
var base64URL = canvas.toDataURL('image/jpeg').replace('image/jpeg', 'image/octet-stream');
this.setState({capturedImage: base64URL})
});
}
Not pretty but should work
this.state = {
RequestData : [],
searchopen : false,
capturedImage : ""
}
screenShot = () => {
var setState = newStore => this.setState((state, props) => ({ ...newStore })); // define the function outside
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
// Get base64URL
var base64URL = canvas.toDataURL('image/jpeg').replace('image/jpeg','image/octet-stream');
setState({capturedImage: base64URL}) // use here
});
}

add JSX element through state in ReactJS

I'm making a chat log which will display userA and userB chat conversation.
My initial state:
var initialState = {
message: '', //my input message
receivedMessage: null //all old messages
}
My handling function when click send button:
handleSend = () => {
var message = () => {
return (<p className="my-text">{this.state.yourName + ": " + this.state.message}</p>);
};
var oldMessages = this.state.receivedMessage;
this.setState({receivedMessage: oldMessages + message, message: ''});
dataChannel.send(message); //WEBRTC data channel
}
My handling received message function:
receiveChannel.onmessage = (event) => {
var oldMessages = this.state.receivedMessage;
var userB = this.state.callToUser;
var message = () => {
return (<p className="receive-text">{userB}: event.data</p>);
}
this.setState({
receivedMessage: oldMessages + message
})
};
My JSX element which store the conversation:
<div className="panel-body text-left">{this.state.receivedMessage}</div>
But this didn't work, I don't get the display I want. Can anybody tell me where did I do wrong and give me a solution for this? Any help is appreciated!

Resources