Function .filter() in ReactJs - reactjs

There is JSON called by fetch() request looks like this:
[{
"Info": "",
"Val": "3"
},
{
"Info": "",
"Val": "5"
},
{
"Info": "",
"Val": "1"
},
{
"Info": "",
"Val": "1"
}]
My purpose is to filter data according a filed called Val.
library = library.filter(item =>
item.Val==FilterVal
)
Let me make an example to explain what I want to do.
Look at this input :<input value={this.state.FilterVal} onChange={this.handlerFilter} />
FilterVal is going to be a number for example 1 or some numbers separated by comma 1,5,4 .
For example user types 1 on input ,the result must return the objects that Valis 1. For the next time type 1,5,4must return me the objects that Val are 1 and 5 and 4.
Here is a piece of my code:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
library: null,
FilterVal: "",
}
}
componentDidMount() {
fetch('/json.bc', {
method: 'POST',
})
.then(response => response.text())
.then(text => {
const Maindata = JSON.parse(text.replace(/\'/g, '"'))
this.setState(state => ({
...state,
data: Maindata
}), () => {
this.reorganiseLibrary()
})
}).catch(error => console.error(error))
})
}
reorganiseLibrary = () => {
const { FilterVal} = this.state;
let library = data;
if (FilterVal !== "") {
library = library.filter(item =>
item.Val==FilterVal
)
}
library = _.chunk(library);
this.setState({
library
})
}
handlerFilter = evt =>
this.setState(
{
FilterVal: evt.target.value
},
() => {
this.reorganiseLibrary();
}
)
renderLibrary = () => {
const { library} = this.state;
if (!library || (library && library.length === 0)) {
return <div>nodata</div>
}
return library.map((item, i) => (
<div>
<span>{item.name}</span>
<span>{item.Val}</span>
</div>
))
}
render() {
const { library} = this.state;
return (
<div>
{this.renderLibrary()}
<input value={this.state.FilterVal} onChange={this.handlerFilter} />
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('Result'))

Just adjust your filter:
const values = FilterVal.split(',').map(v => Number(v))
library = library.filter(item => values.includes(item.Val))

You can use FilterVal.includes(item.Val). This is working solution.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
library: null,
FilterVal: ""
};
}
componentDidMount() {
var originalArray = [
{
Info: "",
Val: "3"
},
{
Info: "",
Val: "3"
},
{
Info: "",
Val: "2"
},
{
Info: "",
Val: "4"
},
{
Info: "",
Val: "4"
},
{
Info: "",
Val: "5"
},
{
Info: "",
Val: "2"
},
{
Info: "",
Val: "1"
}
];
this.setState({ data: originalArray });
}
reorganiseLibrary = () => {
let FilterVal = this.state.FilterVal;
let library = this.state.data;
if (FilterVal !== "") {
FilterVal = FilterVal.split("");
library = library.filter(item => {
if (FilterVal.includes(item.Val)) return item;
});
} else {
library = null;
}
// library = _.chunk(library);
this.setState({
library
});
};
handlerFilter = evt =>
this.setState(
{
FilterVal: evt.target.value
},
() => {
this.reorganiseLibrary();
}
);
renderLibrary = () => {
const { library } = this.state;
if (!library || (library && library.length === 0)) {
return <div>nodata</div>;
}
return library.map((item, i) => (
<div>
<span>{item.name}</span>
<span>{item.Val}</span>
</div>
));
};
render() {
const { library } = this.state;
return (
<div>
{this.renderLibrary()}
<input value={this.state.FilterVal} onChange={this.handlerFilter} />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("Result"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='Result' />

Related

A items List in React looses its all new data rows when edited previous rows, Using custom Uncontrolled Input component

Quick explanation of problem in this image. It's kind of product list where last row is empty and on filling quantity column a new row should appear. Problem is when you have added few new rows and you go back try changing previous rows the newly created rows disappears beyond that point where you made the change.
SANDBOX with all code replicating issue > https://codesandbox.io/s/react-hooks-playground-forked-xbkrub
Index (Main entry point)
import * as React from "react";
import { useState, useEffect } from "react";
import { render } from "react-dom";
import Input from "./Input";
function App() {
const [products, setProducts]: any = useState([]);
const getProductsAsync = () =>
new Promise((resolve, reject) => {
setTimeout(() => {
const prodsArray = [
{
id: 371337,
barcode: null,
name: "4x Cheese",
details: null,
tags: null,
unit: null,
productTimestamp: "2022-01-26T11:40:34.000Z",
activeDate: null,
deleteDate: null,
price: 1
},
{
id: 372093,
barcode: "",
name: "Capri Sun",
details: "",
tags: "",
unit: null,
productTimestamp: "2022-05-11T13:43:37.000Z",
activeDate: "2022-05-11T13:43:37.000Z",
deleteDate: null,
categories: { "924": "Juices", "13524": "3 for £11" },
price: 1
},
{
id: 372552,
barcode: "",
name: "Hot Chocolate",
details: "",
tags: "",
unit: null,
productTimestamp: "2022-05-25T11:15:40.000Z",
activeDate: "2022-05-25T11:15:40.000Z",
deleteDate: null,
categories: { "924": "Juices" },
price: 1
},
{
id: 372553,
barcode: "",
name: "Orange",
details: "",
tags: "",
unit: null,
productTimestamp: "2022-05-25T11:16:06.000Z",
activeDate: "2022-05-25T11:16:06.000Z",
deleteDate: null,
categories: { "924": "Juices" },
price: 1
},
{
id: 372598,
barcode: "",
name: "PRODUCT",
details: "",
tags: "",
unit: null,
productTimestamp: "2022-06-06T14:22:00.000Z",
activeDate: "2022-06-06T14:22:00.000Z",
deleteDate: null,
price: 1
}
];
resolve(prodsArray);
}, 1000);
});
useEffect(() => {
(async () => {
const productObjects: any = await getProductsAsync();
//add a new row at the end for adding more data.
addNewEmptyRow(productObjects);
})();
}, []);
useEffect(() => {}, [products]);
const onPriceChange = (index, event) => {
if (event !== undefined && event.target !== undefined) {
//make sure you supply name="fieldName you want to target in your html tag i.e <input name="taxPercentage">"
const fieldName = event.target.getAttribute("name");
const inputValue = event.target.value;
if (inputValue !== undefined && inputValue !== null) {
const prodComps = products.map((item, currIndex) => {
if (currIndex === index) {
let row = { ...item };
row[fieldName] = inputValue;
return row;
} else {
return item;
}
});
setProducts([...prodComps]);
addNewEmptyRow([...prodComps]);
}
}
};
const addNewEmptyRow = (list: any, rowToAdd?: any) => {
const lastRow = rowToAdd || list[list.length - 1];
if (
lastRow.price !== undefined &&
lastRow.price !== null &&
lastRow.price.toString().length > 0
) {
// enableCrossButtonForLastRow(list);
const rows: any = [
...list,
{
price: "",
vatPercentage: "",
tags: "",
name: " ",
id: null,
autoGenIdForNewlyAddedRow: Date.now(),
showCross: false
}
];
setProducts(rows);
}
};
const generateList: any = () => {
return products.map((item: any, index) => {
return (
<React.Fragment key={item.id || item.autoGenIdForNewlyAddedRow}>
<div>
<input type="text" name="name" value={item.name} readOnly={true} />
</div>
<div>
<Input
type="text"
name="price"
value={item.price}
onChange={(e) => onPriceChange(index, e)}
/>
</div>
<div>X</div>
</React.Fragment>
);
});
};
return (
<div>
<div
style={{
display: "grid",
gridTemplateColumns: "[nameOverride] 175px [price] 155px [cross] 65px"
}}
>
{generateList()}
</div>
</div>
);
}
render(<App />, document.getElementById("root"));
Input.tsx (Custom input component)
import * as React from "react";
import { useEffect, useRef, useState } from "react";
const Input = (props) => {
const [value, setValue] = useState("");
const inputRef: any = useRef(null);
const valueRef = useRef("");
useEffect(() => {
inputRef.current.addEventListener("input", handleChange);
}, []);
useEffect(() => {
if (Boolean(props.value)) {
//this logic sets the data to 2 decimal places
if (props.decimalplaces) {
const val = parseFloat(props.value).toFixed(props.decimalplaces);
valueRef.current = val;
setValue(val);
} else {
valueRef.current = props.value;
setValue(props.value);
}
}
}, [props]);
const handleChange = (e) => {
const val = e.target.value;
if (props.decimalplaces && val.match(/\./g)) {
const [, decimal] = val.split(".");
// restrict value to only 2 decimal places
if (decimal?.length > props.decimalplaces) {
inputRef.current.value = valueRef.current;
} else {
valueRef.current = e.target.value;
}
} else {
valueRef.current = val;
}
if (Boolean(props.onChange)) {
//this builds the custom event object similar to the javascript event object.
props.onChange(
buildEventObject({
value: valueRef.current,
name: props.name,
type: props.type
})
);
}
};
const buildEventObject = (params) => {
return {
target: {
value: params.value,
getAttribute: (key) => {
return params[key];
}
}
};
};
return (
<div>
<input type={props.type} ref={inputRef} defaultValue={value} />
</div>
);
};
export default Input;

Access to api response data

My code pass in a search term and the promise api call returns one record and the data format is as below:
` json api data
0:
{
id:"aff3b4fa-bdc0-47d1-947f-0163ff5bea06"
keyword: somekeyword
URL:"mypage.html"
}
I need to retrieve the URL value, so I try to get URL by using response.data[0].URL. But I receive the error "Unhandled Rejection (TypeError): response.data[0] is undefined". How do I get the URL value? Thanks.
` autocomplete.js
export class Autocomplete extends Component {
state = {
activeSuggestion: 0,
filteredSuggestions: [],
showSuggestions: false,
userInput: "",
suggestions: [],
results: [],
URL: "",
};
componentDidMount() {
this.GetPrograms();
const { userInput } = this.state;
//this.runSearch();
}
GetPrograms = () => {
axios
.get("https://mydomain/GetPrograms/")
.then((response) => {
this.setState({ suggestions: response.data });
});
};
runSearch = async () => {
const response = await axios.get(
"https://mydomain/api/get",
{
params: {
searchTerm: this.state.userInput,
},
}
);
let results = response.data;
console.log("response", results);
this.setState({ results: results, URL: response.data[0].URL });
window.location.href =
"https://mydomain/" + this.state.URL;
};
onChange = (e) => {
const { suggestions } = this.state; //this.props;
const userInput = e.currentTarget.value;
const filteredSuggestions = suggestions.filter(
(suggestion) =>
suggestion.toLowerCase().indexOf(userInput.toLowerCase()) > -1
);
this.setState({
activeSuggestion: 0,
filteredSuggestions,
showSuggestions: true,
userInput: e.currentTarget.value,
});
};
onClick = (e) => {
this.setState({
activeSuggestion: 0,
filteredSuggestions: [],
showSuggestions: false,
userInput: e.currentTarget.innerText,
});
this.onSearch();
console.log(
"child component clicked and value=" + e.currentTarget.innerText
);
};
onKeyDown = (e) => {
const { activeSuggestion, filteredSuggestions } = this.state;
if (e.keyCode === 13) {
this.setState({
activeSuggestion: 0,
showSuggestions: false,
userInput: filteredSuggestions[activeSuggestion],
});
} else if (e.keyCode === 38) {
if (activeSuggestion === 0) {
return;
}
this.setState({ activeSuggestion: activeSuggestion - 1 });
} else if (e.keyCode === 40) {
if (activeSuggestion - 1 === filteredSuggestions.length) {
return;
}
this.setState({ activeSuggestion: activeSuggestion + 1 });
}
//this.setState({ searchTerm: e.currentTarget.value });
console.log("userinput:" + this.state.userInput);
};
render() {
const {
onChange,
onClick,
onKeyDown,
onKeyPress,
state: {
activeSuggestion,
filteredSuggestions,
showSuggestions,
userInput,
},
} = this;
let suggestionsListComponent;
if (showSuggestions && userInput) {
if (filteredSuggestions.length) {
suggestionsListComponent = (
<ul class="suggestions">
{filteredSuggestions.map((suggestion, index) => {
let className;
if (index === activeSuggestion) {
className = "";
}
return (
<li key={suggestion} onClick={onClick}>
{suggestion}
</li>
);
})}
</ul>
);
} else {
suggestionsListComponent = (
<div class="no-suggestions">
<em>No suggestions</em>
</div>
);
}
}
return (
<div>
<input
id="search-box"
placeholder="Search..."
type="search"
onChange={onChange}
onKeyDown={onKeyDown}
value={userInput}
/>
{suggestionsListComponent}
</div>
);
}
}
export default Autocomplete;
`
The api call returns 0 record that causes the error.

React: disable a filtered item

I am creating an activity, where a user needs to match two words on click. Like on the picture below.
If words match they should get disabled.
My state is following
this.state = {
data: [],
mixedWords: [],
myanswers: [],
allPairs: [],
checked: false,
isCorrect: false,
isIncorrect: false
};
For example myanswers array maybe like this.
["more than", "более"]
mixedWords array is the following
[{translation: "more than", disabled: false},
{translation: "capital", disabled: false},
{word: "более", disabled: false},
{translation: "famous", disabled: false},
{word: "проживает", disabled: false},
{translation: "is living", disabled: false},
{word: "известный", disabled: false},
{word: "столице", disabled: false}
]
This function is responsible for modifying disabled property. But the problem is that it outputs only filtered items. How can I output mixedWords array with modifyed disabled property for specific items
const myFunction = (value) => {
const mixedWords = [...this.state.mixedWords]
const result = mixedWords.filter(word => word.translation === value || word.word === value );
const newResult = Object.assign({}, result[0], { disabled:true })
this.setState({
mixedWords:[newResult]
})
}
this.state.myanswers.forEach(myFunction)
Full code
/* eslint-disable no-extend-native */
import React, { Component } from "react";
//import click from "../data/media/click.wav";
//import correct from "../data/media/correct.wav";
//import denied from "../data/media/denied.mp3";
let _ = require("lodash");
class Quiz extends Component {
constructor (props) {
super(props);
this.state = {
data: [],
mixedWords: [],
myanswers: [],
allPairs: [],
checked: false,
isCorrect: false,
isIncorrect: false
};
}
componentDidMount() {
let mixedWords = [];
let allPairs = [];
this.props.data.quiz && this.props.data.quiz.map((item) => {
mixedWords.push({word:item.word, disabled:false},{ translation:item.translation,disabled:false});
allPairs.push(item.pair);
return (mixedWords, allPairs);
});
this.setState({
data: this.props.data.quiz,
mixedWords: _.shuffle(mixedWords),
allPairs
});
//console.log(this.props.data);
}
selectWords = (e) => {
let items = e.target.value;
let myanswers = this.state.myanswers.concat(items);
this.setState({ myanswers }, () => {
if (this.state.myanswers.length === 2) {
if (this.checkAnswers(this.state.myanswers, this.state.allPairs)) {
console.log("correct");
const myFunction = (value) => {
const mixedWords = [...this.state.mixedWords]
const result = mixedWords.filter(word => word.translation === value || word.word === value );
const newResult = Object.assign({}, result[0], { disabled:true })
this.setState({
mixedWords:[newResult]
})
}
this.state.myanswers.forEach(myFunction)
this.setState({
myanswers:[]
})
} else {
console.log("incorrect");
this.setState({
myanswers:[]
})
}
} else {
console.log('choose a pair');
}
});
};
checkAnswers = (answersArr, allPairs) => {
let bools = []
allPairs.forEach((arr) => {
this.arraysEqual(answersArr, arr);
//console.log(this.arraysEqual(answersArr, arr));
//console.log(arr, this.state.myanswers);
bools.push(this.arraysEqual(answersArr, arr))
});
if (bools.includes(true)) {
return true
}
};
arraysEqual = (a, b) => {
return a.sort().toString() === b.sort().toString()
};
render() {
console.log(this.state.mixedWords);
console.log(this.state.myanswers);
//console.log(this.state.allPairs);
//console.log(this.state.myanswers.join(" ") === this.state.answers.join(" "));
return (
<div>
<div className="tags are-medium">
{ this.state.mixedWords.map((item) => (
<button disabled={item.disabled} value={ item.word || item.translation } onClick={ (e) => { this.selectWords(e); } } className="tag is-warning">{ item.word || item.translation }</button>
)) }
</div>
</div>
);
}
}
export default Quiz;
selectWords = (e) => {
let items = e.target.value;
let myanswers = this.state.myanswers.concat(items);
this.setState({ myanswers }, () => {
if (this.state.myanswers.length === 2) {
if (this.checkAnswers(this.state.myanswers, this.state.allPairs)) {
console.log("correct");
const myFunction = (value) => {
this.setState({
mixedWords:this.state.mixedWords.map(word => word.translation === value || word.word === value ? Object.assign({}, word, { disabled:true }) : word)
})
}
this.state.myanswers.forEach(myFunction)
this.setState({
myanswers:[]
})
} else {
console.log("incorrect");
this.setState({
myanswers:[]
})
}
} else {
console.log('choose a pair');
}
});
};

How to Send message by just clickiing on the suggestion in Botframework-Webchat?

I want my bot to send the message when i click on the desired suggestion. i.e. i want the message to be sent - when i click on the suggestion or by selecting the suggestion using arrow keys and then pressing enter . But as of now, if i click or select the suggestion using arrow keys - the suggestion value comes to the text box and then i have to press enter to send the message. I just want to change that.
Any help would be greatly appreciated
My code is as follows,
import React from 'react';
import { DirectLine, ConnectionStatus } from 'botframework-directlinejs';
import ReactWebChat from 'botframework-webchat';
import './ChatComponent.css';
var val;
var apiParameters = [];
var currentFocus = -1;
export default class extends React.Component {
constructor(props) {
super(props);
this.state = {
token: '',
conversationId: '',
directLine: {},
view: false,
feedBack: null,
value: '',
popupContent: '',
storeValue: '',
suggestions: [],
suggestionCallback: '',
suggestionTypedText: "",
typingChecking: "false",
};
this.handleTokenGeneration = this.handleTokenGeneration.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleSaveFeedback = this.handleSaveFeedback.bind(this);
this.handleSuggestion = this.handleSuggestion.bind(this);
this.handleClose = this.handleClose.bind(this);
this.handleSuggestionClick = this.handleSuggestionClick.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.moveHighlight = this.moveHighlight.bind(this);
this.getSuggestionHtml = this.getSuggestionHtml.bind(this);
}
getSuggestionHtml(suggestion) {
const lowerCaseSuggestion = suggestion.toLowerCase();
return {
__html: lowerCaseSuggestion.includes(this.state.suggestionTypedText) ? lowerCaseSuggestion
.replace(this.state.suggestionTypedText, `<b>${this.state.suggestionTypedText}</b>`) : lowerCaseSuggestion
};
}
handleTokenGeneration = async () => {
console.log("11111");
const response = await fetch(`api/TokenGenerationService/GetToken`);
const data = await response.json();
this.setState({ token: data.categoryObject.token, conversationId: data.categoryObject.conversationId });
this.state.directLine = new DirectLine({ token: this.state.token });
this.setState({ view: true });
this.setState({ typingChecking: "true" });
console.log("conversationId");
};
async handleSuggestion(val, store) {
if (val === "") {
this.setState({
suggestions: []
});
}
else {
apiParameters = [];
var valuess = null;
const response = await fetch(`api/TokenGenerationService/GetAzureSearch?myparam1=${val}`);
const data = await response.json();
var values = ["Hello", "yes", "no", "exit", "Welcome", "Thank You", "Approve", "Apply leave", "Reject", "Absence Balance", "Leave Balance", "Upcoming Holidays", "Apply Comp-Off", "Approve Leave", "Raise Incident Tickets", "Project Allocation Info", "Reporting Manager Change", "Reporting Manager Approval", "Approve Isolve Tickets", "My Manager", "My Account Manager", "Generate Salary Certificate", "Isolve Ticket Status", "Internal Job Posting", "My Designation", "My Joining Date", "RM Approval", "RM Change", "Resource Allocation", "ESettlement Approval", "SO Approval", "Cash advance Approval", "Purchase Request Approval", "Referral status", "HR Ticket", "Platinum Support"];
valuess = values.filter(s =>
s.toLocaleLowerCase().startsWith(val.toLowerCase())
);
valuess = valuess.concat(data.az_search);
this.setState({
suggestions: valuess,
suggestionCallback: store,
suggestionTypedText: val.toLowerCase()
});
var totCount = data.az_search;
console.log("kkkkkk" + totCount);
var myNode = document.getElementById('Suggestion1');
}
}
getSuggestionCss(index) {
var HIGHLIGHTED_CSS = "HIGHLIGHTED_CSS";
var SUGGESTION_CSS = "SUGGESTION_CSS";
console.log("jioouu" + this.state.highlightedIndex);
return index === this.state.highlightedIndex ? HIGHLIGHTED_CSS : SUGGESTION_CSS;
}
moveHighlight(event, direction) {
event.preventDefault();
const { suggestions, highlightedIndex=-1 } = this.state;
if (!suggestions.length) return;
let newIndex = (highlightedIndex + direction + suggestions.length) % suggestions.length;
console.log("lokkkk" + direction)
if (newIndex !== highlightedIndex) {
console.log("kkkkkkkkkkkkkkkkkkk")
this.setState({
highlightedIndex: newIndex,
});
}
}
keyDownHandlers = {
ArrowDown(event) {
this.moveHighlight(event, 1);
},
ArrowUp(event) {
this.moveHighlight(event, -1);
},
Enter(event) {
const { suggestions } = this.state;
if (!suggestions.length) {
// menu is closed so there is no selection to accept -> do nothing
return
}
event.preventDefault()
this.applySuggestion(suggestions[this.state.highlightedIndex]);
},
}
handleKeyDown(event)
if (this.keyDownHandlers[event.key])
this.keyDownHandlers[event.key].call(this, event)
}
async handleSuggestionClick(event) {
await this.applySuggestion(event.currentTarget.textContent);
}
async applySuggestion(newValue) {
await this.setState({ typingChecking: "false", suggestions: [], highlightedIndex: 0 });
this.state.suggestionCallback.dispatch({
type: 'WEB_CHAT/SET_SEND_BOX',
payload: {
text: newValue,
}
});
await this.setState({ typingChecking: "true" });
}
handleClose(elmnt) {
var x = document.getElementsByClassName("autocomplete-items");
for (var i = 0; i < x.length; i++) {
if (elmnt !== x[i]) {
x[i].parentNode.removeChild(x[i]);
}
}
}
async componentDidMount() {
try {
await this.handleTokenGeneration();
const store =
window.WebChat.createStore(
{},
({ getState }) => next => action => {
this.state.directLine.connectionStatus$
.subscribe(connectionStatus => {
//console.log("connect" + connectionStatus);
//console.log("LOP" + ConnectionStatus.ExpiredToken);
if (connectionStatus === ConnectionStatus.ExpiredToken) {
console.log("expired");
}
if (action.type === 'WEB_CHAT/SET_SEND_BOX') {
const val = action.payload.text;
if (this.state.typingChecking === "true") {
this.setState({
highlightedIndex: -1,
});
console.log(this.state.typingChecking);
this.handleSuggestion(val, store);
}
}
if (action.type === 'DIRECT_LINE/DISCONNECT_FULFILLED') {
console.log("final" + connectionStatus);
console.log("finalexpired" + ConnectionStatus.ExpiredToken);
console.log("final");
this.handleTokenGeneration();
// fetch('api/TokenGenerationService/GetToken').then(conversation => this.state.directLine.reconnect(conversation))
}
});
return next(action)
}
);
this.setState({ storeValue: store });
} catch (error) {
console.log("error in fetching token");
console.log(error);
}
this.state.directLine.activity$
.filter(activity => activity.type === 'message')
.subscribe(function (activity)
{
//console.log("oooooooooooooooooooooo");
}
// message => console.log("received message ", message.text)
);
}
handleSaveFeedback(ans) {
var userID = "U92656";
var feedbackmsg = this.state.value;
var feedbacktype = this.state.feedBack;
var convId = this.state.conversationId;
fetch('api/Feedback/SaveFeedback',
{
method: "POST",
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ Uid: userID, FeedbackMessage: feedbackmsg, Convid: convId, FeedbackType: feedbacktype })
}).
then(response => response.text())
.then(data => {
console.log(data.getResult);
});
this.setState({ value: '' });
}
feedback(ans) {
this.setState({ feedBack: ans });
if (ans === "Send") {
this.handleSaveFeedback(ans);
}
else if (ans === "Yes") {
this.setState({ popupContent: "How was your experience?" });
// console.log(this.state.value)
}
else if (ans === "No") {
this.setState({ popupContent: "What went wrong?" });
// console.log(this.state.value)
}
}
handleChange = (event) => {
this.setState({ value: event.target.value });
}
render() {
if (!this.state.view) {
return <div />
} else {
const filteredSuggestions = this.state.suggestions.filter(
suggestion =>
suggestion.toLowerCase().indexOf(this.state.suggestionTypedText.toLowerCase()) > -1
);
return (
<div className="react-container webchat" >
<div onKeyDown={this.handleKeyDown.bind(this)}>
<div >
<ReactWebChat directLine={this.state.directLine} webSocket={true} userID='U92656' username='Thomas' store={this.state.storeValue} sendTypingIndicator={true} />
</div>
</div>
<div className="SuggestionParent" id="Suggestion1">
{this.state.suggestions.map((suggestion, index)=> (
<div className={this.getSuggestionCss(index)} key={index} onClick={this.handleSuggestionClick} >
{suggestion
.toLowerCase()
.startsWith(this.state.suggestionTypedText) ? (
<div>
<b>{this.state.suggestionTypedText}</b>
{suggestion
.toLowerCase()
.replace(this.state.suggestionTypedText, "")}
</div>
) : (
<div dangerouslySetInnerHTML={this.getSuggestionHtml(suggestion)} />
)}
</div>
))}
</div>
<footer className="chat-footer" >
<div className="foot-footer">
Was I helpful ?
<span className="feedback" onClick={() => this.feedback("Yes")} >Yes</span><span>|</span><span className="feedback" onClick={() => this.feedback("No")}>No</span>
{
this.state.feedBack === "Yes" || this.state.feedBack === "No" ?
(
<div className="dialog" id="myform">
<div id="textfeedback">
<span id="closeFeedback" onClick={() => this.feedback("Close")}>X</span>
<p>{this.state.popupContent}</p>
<input type="text" id="feedbacktxtbox" required name="textfeedback" placeholder="Pleasure to hear from u!"
onChange={this.handleChange}
value={this.state.value} />
<button type="button" id="btnfeedback" onClick={() => this.feedback("Send")}>send</button>
</div>
</div>
) : null
}
</div>
</footer>
</div>
);
}
}
}

Sorting an array that is in another array in ReactJs

I have a json file called by fetch request that looks like this:
[
{
"Infos": [
{
"id": {
"Id": "105254"
},
"total": 142854739
},
{
"id": {
"Id": "105255"
},
"total": 112854739
},
{
"id": {
"Id": "105256"
},
"total": 132854739
},
{
"id": {
"Id": "106540"
},
"total": 122868818
}
]
}
]
I want to sort data based on total field ,but as you can see all objects are in another array called Infos and I can not to sort data like this:
Maindata.sort((a, b) => a.total - b.total);
How can I sort data based on total field that is in another an array?
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
library: null,
perPage: 20,
currentPage: 1,
maxPage: null,
}
}
componentDidMount() {
fetch('/json.bc', {
method: 'get',
})
.then(response => response.text())
.then(text => {
let Maindata = JSON.parse(text.replace(/\'/g, '"'))
Maindata.sort((a, b) => a.Infos[i].total - b.Infos[i].total) // I want to sort data here /////
this.setState(state => ({
...state,
data: Maindata
}), () => {
this.reorganiseLibrary()
})
}).catch(error => console.error(error))
}
reorganiseLibrary = () => {
const { perPage, data } = this.state;
let library = data;
library = _.chunk(library, perPage);
this.setState({
library,
currentPage: 1,
maxPage: library.length === 0 ? 1 : library.length
})
}
// Previous Page
previousPage = event => {
this.setState({
currentPage: this.state.currentPage - 1
})
}
// Next Page
nextPage = event => {
this.setState({
currentPage: this.state.currentPage + 1
})
}
// handle per page
handlePerPage = (evt) =>
this.setState({
perPage: evt.target.value
}, () => this.reorganiseLibrary());
// handle render of library
renderLibrary = () => {
const { library, currentPage } = this.state;
if (!library || (library && library.length === 0)) {
return <div>NOResult</div>
}
return library[currentPage - 1].map((item, i) => (
<div className="Wrapper">{this.renderInfo(item)}</div>
))
}
renderInfo(element){
let len =element.Infos.length
for (let i = 0; i < len; i++) {
return element.Infos[i].total
}
}
render() {
const { library, currentPage, perPage, maxPage } = this.state;
return (
<div>
{this.renderLibrary()}
<ul id="page-numbers">
<li className="nexprevPage">
{currentPage !== 1 && (
<button onClick={this.previousPage}><span className="fa-backward"></span></button>
)}
</li>
<li className="controlsPage activeCnt">{this.state.currentPage}</li>
<li className="restControls">...</li>
<li className="controlsPage">{this.state.maxPage}</li>
<li className="nexprevPage">
{(currentPage < maxPage) && (
<button onClick={this.nextPage}><span className="fa-forward"></span></button>
)}
</li>
</ul>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('Result'))
You can sort the inner field by mapping over the outer array and sorting the inner one like
Maindata = Maindata.map((data) => ({Infos: data.Infos.sort((a, b) => a.total - b.total)}))

Resources