In react How to split the handle change value in react - javascript

I need to get the array of handle change value and pass into the API URL. I'll share my code.
import React from 'react';
import Select from 'react-select';
const Selects = [
{
name: 'firstSelect',
options: [
{ value: 1, label: 'Vg' },
{ value: 2, label: 'sri' }
]
},
{
name: 'secondSelect',
options: [
{ value: 1, label: 'akila' },
{ value: 2, label: 'selvi' },
{ value: 3, label: 'shanmuga' }
]
}
];
export default class Demo extends React.Component {
onSelectChange(name, value) {
let obj = [];
obj[name] = value;
this.setState(obj);
console.log(obj[name].value);
let url =
'http://localhost:99999/api/GetProfile/Get_MyPostDetails?id=3&Year=' +
obj[name].value +
'&CategoryID=' +
obj[name].value;
let user = JSON.parse(localStorage.getItem('user'));
const accessToken = user;
console.log(accessToken);
//console.log("hi");
fetch(url, {
method: 'GET',
headers: {
'Content-type': 'application/json',
Accept: 'application/json',
Authorization: 'Bearer ' + accessToken,
'Access-Control-Allow-Headers': 'Access-Control-Request-Headers '
}
//body:JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
this.setState({
like: data
});
console.log('Filter', data);
// console.log(emps.profile_dateOfAnniversary);
});
}
render() {
return (
<div>
{Selects.map((select, i) => {
return (
<Select
key={i}
name={select.name}
options={select.options}
onChange={this.onSelectChange.bind(this, select.name)}
/>
);
})}
</div>
);
}
}
When I select the First dropdown value it passes into the Year and Category Id also. I need to select the first dropdown value pass into the year and the second value is set into the CategoryId. Please share your Idea.
Thanks in Advance.

this.setState is asynchronous
When your use state in API Url first time, your state is empty yet. When you do it second time state have data from first this.setState call.
Your must do API call in seState callback:
this.setState(
(prev) => {
return {
...prev,
[name]: {
...prev[name],
value: value.value
}
};
},
() => {
//state will be updated and you can send API call
}
);

Related

Need SPLIT ARRAY for post in API

I have a question form where the administrator can choose whether the question will be objective or multiple choice, but when the user marks 2 checkboxes, I pass the ID to the API and it cannot receive an array just an integer. I need to separate the array and pass it unitarily
PAYLOAD
0: {survey: {id: "252"}, question: {id: "385"}, personSurvey: {id: "246"},…}
personSurvey: {id: "246"}
question:{id: "385"}
questionAlternative: {id: [["367", "369"]]}
survey: {id: "252"}`
My HandleSubmit
function handleSubmit(data: any) {
setLoading(true);
apiBase.create("answer/all", data.answer);
survey &&
apiBase
.find<IEventDetailDTO>(
"event-detail",
`typeDetail=ID&eventEventTypeId=3&idReference=${survey.id}`,
)
.then(
({ data: eventDetails }) =>
eventDetails[0] &&
apiBase.patch(
"event-detail",
eventDetails[0],
{ dateSurveyAnswered: nowDate() },
{ headers: { noMessage: true } },
),
);
apiBase
.patch(
"/person-survey",
{ id: personSurveyId },
{ statusTarget: "RESPONDIDO" },
{ headers: { noMessage: true } },
)
.then(() => setLoading(false));
}
FORM Component
const getValue = (choiceRef) => {
const values = choiceRef.filter((i) => i.checked).map((i) => i.value);
return [values];
};
I need the questionAlternative ID to be passed separately and that it not lose the question id reference

How to add multiple values to an object ID later in mongodb

I am trying to add values inside the object id. Object id is created before but I want to add more values in the future inside the object ID.
This is my MongoDB database:
[{
label: 'colors',
options: [
{ label: 'Black', value: 1 },
{ label: 'Green', value: 2 },
]
}]
My expectation is when I will send a new object it will insert a new object inside the options property. suppose my new object is {label: 'blue', value: 3} it will be like this:
[{
label: 'colors',
object: [
{ label: 'Black', value: 1 },
{ label: 'Green', value: 2 },
{label: 'blue', value: 3}
]
},
I am trying this way, I am storing the previous data value, inserting a new value, and sending it to the backend. but it's not working. is there any different way I can fix it?
const addAttributeValues = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
if (label === '') {
return
}
const slug = label?.split(' ').join('-')
const options: any = [] // previous value storing
let update; // inserting previous and new value
if (attr.options) { // checking if the previous data has options property or not
options.push(attr.options)
const length: any = options.length
update = { options: { ...options, [length]: { label, slug } }, id: attr._id }
}
else { // if option property doesn't exist it means no new value added before
update = { options: { label, slug }, id: attr._id }
}
fetch('http://localhost:5000/dashboard/attributes', {
method: 'PUT',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(update)
})
.then(res => res.json())
.then(data => {
setLabel('')
setIfShouldUpdate(true)
})
}
Backend API, I use put method, I don't know is there any other method for inserting new values in the future.
// ADD ATTRIBUTES VALUE
app.put('/dashboard/attributes/', async (req, res) => {
const { options, id } = req.body
const filter = { _id: objectId(id) }
const updateDoc = {
$set: {
options: options
},
};
const result = await unityMartAttributes.updateOne(filter, updateDoc);
res.json(result)
console.log(result);
})
You need to use $push to add new object in your array. $set will reset your previous values with new one. Also don't use ObjectId, just pass simple id which needs to be string. And if you want to pass in ObjectId then use
mongoose.Types.Objectid(id)

React Redux store changes sometimes rerender and sometimes dont

So i am using the fetch API with react / redux to perform API calls to Blockv in my actions and store a returned array of objects in my redux store using a reducer. My array of objects only contains one level of objects (i.e. {id: 9798234982739847, name: 220398402343, etc..}). My table that SHOULD rerender everytime the array is replaced - and I use replace as i want to completely replace the array in the store with the new - only rerenders sometimes and i can see the changes reflected in the store.
I am using thunk middleware. Here is what im working with:
store.js
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { createLogger } from 'redux-logger'
import urbanArcadeReducer from '../reducers/reducers'
import { loadTokens } from '../localStorage'
import { checkAuth } from '../actions/check-auth'
const persistedTokens = loadTokens();
const loggerMiddleware = createLogger();
// Store for Urban Arcade Application
const store = createStore(
urbanArcadeReducer,
persistedTokens,
applyMiddleware(
thunk, // lets us dispatch() functions
loggerMiddleware // neat middleware that logs actions
)
)
// Check for automatic login on page load
store.dispatch(checkAuth(store.getState().access_token))
export default store
reducers.js
function atoms(state = {
receivedAt: null,
atoms: []
}, action) {
switch (action.type) {
case UPDATE_CURR_ATOMS:
var mappedAtoms = action.atoms.map(atom => {
atom = {
id: atom.id,
gameTitle: atom.private.GameTitle,
highscore: atom.private.HighScore,
highscoreOwner: atom.private.HighScoreOwner,
locationName: atom.private.LocationName,
scoreHistory: atom.private.ScoreHistory,
unpublished: atom.unpublished,
author: atom['vAtom::vAtomType'].author,
description: atom['vAtom::vAtomType'].description,
dropped: atom['vAtom::vAtomType'].dropped,
lat: atom['vAtom::vAtomType'].geo_pos.coordinates[1],
lng: atom['vAtom::vAtomType'].geo_pos.coordinates[0],
owner: atom['vAtom::vAtomType'].owner,
template: atom['vAtom::vAtomType'].template,
template_variation: atom['vAtom::vAtomType'].template_variation,
title: atom['vAtom::vAtomType'].title,
when_created: atom.when_created,
when_modified: atom.when_modified
}
return atom
})
return {
...state,
receivedAt: action.receivedAt,
atoms: mappedAtoms
}
default:
return state
}
}
actions.js
import {
fetchRequest,
fetchFailure,
fetchSuccess,
updateNotifier,
updateCurrAtoms } from './action-creators'
import { bringToLogin } from './bring-to-login'
export const UPDATE_CURR_ATOMS = 'UPDATE_CURR_ATOMS'
export function updateCurrAtoms(atoms) {
return { type: UPDATE_CURR_ATOMS, atoms: atoms.atoms, receivedAt: atoms.receivedAt }
}
/**
* Submits request to get all arcade games using Blockv Discover Endpoint(vAtoms)
*
* #returns list of arcade cabinets (vAtoms)
*/
export function getAtoms(params) {
var access_token = params.access_token
var from_refresh = params.from_refresh
var responseCode = ''
var method = 'POST'
var url = 'https://api.blockv.io/v1/vatom/discover'
var headers = {
'Content-Type': 'application/json',
'App-Id': '<App ID>',
'Authorization': 'Bearer ' + access_token
}
var requestBody = {
"scope": {
"key": "vAtom::vAtomType.template",
"value": "<publisher_fqdn>"
},
"filters": [
{
"filter_elems": [
{
"field": "vAtom::vAtomType.template",
"filter_op": "Match",
"value": "<publisher_fqdn>"
}
]
}
],
"return": {
"type": "*",
}
}
var requestBodyJSON = JSON.stringify(requestBody)
// Thunk middleware knows how to handle functions.
// It passes the dispatch method as an argument to the function,
// thus making it able to dispatch actions itself.
return function(dispatch) {
// First dispatch: the app state is updated to inform
// that the API call is starting.
dispatch(fetchRequest())
console.log('Sending get atoms request to Blockv...');
fetch(url, {
method: method,
body: requestBodyJSON,
headers: headers
}).then(response => {
responseCode = response.status
console.log(responseCode)
return response.json()
}).then(data => {
if (responseCode === 401) {
dispatch(bringToLogin("We've logged you out. Please reauthenticate"))
dispatch(fetchFailure('Failed to get atoms'))
} else if (responseCode === 200) {
var atoms = data.payload.results
dispatch(fetchSuccess('Retrieved atoms!')) // Array of template variations
if (from_refresh) {
dispatch(updateNotifier({
isOpen: true,
message: 'Successfully retrieved games!'
}))
}
dispatch(updateCurrAtoms({
atoms: atoms,
receivedAt: Date.now()
}))
}
}).catch(err => {
console.log(err)
dispatch(fetchFailure('Failed to get atoms'))
});
}
}
MyComponent.js
...
class GameStatsModal extends Component {
getDataAtoms = () => {
return this.props.atoms
}
/**
* Props for each row in table
*
* #memberof GameStatsModal
*/
setTrProps = (state, rowInfo, column, instance) => {
return {
style: {
marginBottom: 15
}
}
}
render () {
return (
<OuterContainer>
<StatsContainer>
<InnerContainer>
<img
src={RefreshIcon}
alt="Refresh List"
id="refreshGames"
className='refreshButton'
onClick={
() => {
store.dispatch(getAtoms({
access_token: store.getState().access_token,
from_refresh: true
}))
}
}
/>
<ReactTable
data={this.getDataAtoms()}
className='-highlight -striped gamesTable'
noDataText="Click Refresh to Load Games"
columns={columnsAtoms}
defaultSorted={[{id: 'created', desc: true}]}
getTrProps={this.setTrProps}
getTdProps={this.setTdProps}
pageSize={this.getDataAtoms().length}
showPagination={false}
resizable={false}
/>
</InnerContainer>
</StatsContainer>
</OuterContainer>
)
}
}
const mapStateToProps = state => ({
atoms: state.atoms.atoms
})
export default withRouter(connect(mapStateToProps)(GameStatsModal))
Again i know the updates are being made to store, so my question is am i somehow mutating the previous state somewhere? If not is it possible that since i have multiple dispatch calls being executed in actions, could they be interfering with each other and/or rerendering? not sure where else to look.
Looking forward to any suggestions, thank you!
i think you are mutating the state directly
try this one
switch (action.type) {
case UPDATE_CURR_ATOMS:
var mappedAtoms = action.atoms.map(atom => {
// directly returning the new object
return {
id: atom.id,
gameTitle: atom.private.GameTitle,
highscore: atom.private.HighScore,
highscoreOwner: atom.private.HighScoreOwner,
locationName: atom.private.LocationName,
scoreHistory: atom.private.ScoreHistory,
unpublished: atom.unpublished,
author: atom['vAtom::vAtomType'].author,
description: atom['vAtom::vAtomType'].description,
dropped: atom['vAtom::vAtomType'].dropped,
lat: atom['vAtom::vAtomType'].geo_pos.coordinates[1],
lng: atom['vAtom::vAtomType'].geo_pos.coordinates[0],
owner: atom['vAtom::vAtomType'].owner,
template: atom['vAtom::vAtomType'].template,
template_variation: atom['vAtom::vAtomType'].template_variation,
title: atom['vAtom::vAtomType'].title,
when_created: atom.when_created,
when_modified: atom.when_modified
}
})
return {
...state,
receivedAt: action.receivedAt,
atoms: mappedAtoms
}

How can I disable checkboxes and radio buttons from separate components?

Running into this ReactJS (with Redux) issue:
If premium white isn’t selected, gloss finish should be disabled. The radio button (premium) and checkbox (gloss) have separate methods in separate components – looks like they are both using state to send data.
Here’s the checkbox
buildCheckbox(item) {
return (
<Checkbox
key={item.key}
label={item.display}
name={item.key}
checked={this.props.order[item.key] || false}
onChange={checked => this.handleCheck(checked, item.key)}
disabled={item.disabled(this.props.order)}
/>
);
}
And the handleclick method used
handleCheck(checked, key) {
const { params, updateOrder } = this.props;
const { sessionId } = params;
// if doulbeSided option is removed, then clear the inside file.
if (key === 'doubleSided' && !checked) {
updateOrder(sessionId, { inside: null });
}
// set ink coverage based on printed flag
if (key === 'printed') {
const inkCoverage = checked ? 100 : 0;
updateOrder(sessionId, { inkCoverage });
}
// if unprinted, remove doublesided and gloss options
if (key === 'printed' && !checked) {
updateOrder(sessionId, { doubleSided: false });
updateOrder(sessionId, { gloss: false });
}
updateOrder(sessionId, { [key]: checked });
}
And the radio button’s method
onClick(id, ordAttribute) {
const { updateOrder, sessionId, validator } = this.props;
updateOrder(sessionId, { [ordAttribute]: id });
if (validator) validator(ordAttribute);
}
I saw that gloss has a service which is toggling disabled or not via the printed key on state here
gloss: {
display: 'Gloss Finish',
key: 'gloss',
component: 'checkbox',
disabled: state => !state.printed,
},
I’ve thought about creating a fourth radio button and just deleting the gloss option but I’m not sure where it’s being populated from – also thought about using a display none on the styles of the gloss that is activated via the radio button – but am not sure where to start.
just stated a new job and this is the previous employee's code - trying to figure it out. looks like the state is activated via this Action method:
export const updateOrder = (sessionId, payload) => (dispatch, getState) => {
dispatch(updateAction({ ...payload }));
const state = getState();
const ord = getNewOrderForm(state);
const minOrdValue = getMinOrdValue(state);
const { length, width, height, style, blankLength, blankWidth, qty, leadTime, sqFeet } = ord;
const priceMatrix = style ? getPriceMatrix(state)[style.priceMatrix] : null;
if (priceMatrix && style && style.calcPrice) {
dispatch(dispatchNewPrice(ord, style, priceMatrix, minOrdValue));
}
if (shouldCalcBlank({width, length, height}, style)) {
calcBlanks(style, {width, length, height})
.then(blanks => dispatch(updateAction(blanks)))
.catch(err => console.log('error', err))
}
if (blankLength && blankWidth && qty) {
calcSquareFeet({ blankLength, blankWidth, qty })
.then(sqFeet => {
dispatch(updateAction({ sqFeet }));
return sqFeet;
})
.then(sqFeet => sqFeet > 1000)
.then(lrgSqFeet => {
dispatch(updateAction({ lrgSqFeet }));
return lrgSqFeet;
})
.then(lrgSqFeet => {
if (lrgSqFeet && leadTime === 'rush') {
dispatch(updateAction({ leadTime: 'standard' }));
}
});
}
if (sqFeet && (!blankLength || !blankWidth || !qty)) {
dispatch(updateAction({ sqFeet: 0 }));
}
localStorage.setItem(sessionId, JSON.stringify(getNewOrderForm(getState())));
};
i thought about adding a the radio button has an id of 'clearwater' so i thought about adding a bool to this method that could then be accessed as clearwater: false (and when onClick is activated, updateOrder then changes it to clearwater: true, and then the gloss object in the service would then check disabled: state => !state.printed && !state.clearwater (this didn't work):
export const generateNewOrder = (userid, style, sessionId = uuid()) => dispatch => {
localStorage.setItem(
sessionId,
JSON.stringify({
userid,
style,
sessionId,
blindShip: true,
inkCoverage: '100',
printed: true,
})
);
history.push(`/order/new/${style.styleCode}/${sessionId}`);
dispatch(
newOrder({
userid,
style,
sessionId,
blindShip: true,
inkCoverage: '100',
printed: true,
})
);
if (style.type === 'static') {
const { dims, blankLength, blankWidth } = style;
const payload = {
...dims,
blankLength,
blankWidth,
};
dispatch(updateOrder(sessionId, payload));
}
};
I was hoping by changing the Service attached to the checkbox, I could add an additional condition that would cause the disabled functionality to be dependent on the state.boardStyle, but this doesn't seem to work (picture below isn't accurate, i changed it to boardStyle):
http://oi65.tinypic.com/wknzls.jpg
This is using redux -- kind of new to redux -- let me know if I'm missing any info -- I will post anything to get this solved.
Any help would be huge – thanks so much!
i think i figured it out . . .
there's probably a drier way to do this, but here goes:
first i created a new key [bool] (clearwater, set to false) on generateNewOrder method in Actions:
export const generateNewOrder = (userid, style, sessionId = uuid()) => dispatch => {
localStorage.setItem(
sessionId,
JSON.stringify({
userid,
style,
sessionId,
blindShip: true,
inkCoverage: '100',
printed: true,
clearwater: false,
})
);
history.push(`/order/new/${style.styleCode}/${sessionId}`);
dispatch(
newOrder({
userid,
style,
sessionId,
blindShip: true,
inkCoverage: '100',
printed: true,
clearwater: false
})
);
if (style.type === 'static') {
const { dims, blankLength, blankWidth } = style;
const payload = {
...dims,
blankLength,
blankWidth,
};
dispatch(updateOrder(sessionId, payload));
}
};
that gave me access to this state value, which i could then use in the onclick when the radio button was pressed. if the id was clearwater, the bool would be set to true, else it was set to false (only for the other two options because this code is used for other IDs)
onClick(id, ordAttribute) {
const { updateOrder, sessionId, validator } = this.props;
updateOrder(sessionId, { [ordAttribute]: id });
if (validator) validator(ordAttribute);
if (id === 'clearwater') {
updateOrder(sessionId, { clearwater: true });
} else if (id === 'kraft' || id === 'std_white_two_side'){
updateOrder(sessionId, { clearwater: false });
}
}
then all i needed to do was add this to the Service. if it was not printed !printed or not clearwater !clearwater, the checkbox would be disabled
const printing = {
doubleSided: {
display: 'Two Sided Print',
key: 'doubleSided',
component: 'checkbox',
disabled: state => !state.printed,
},
printed: {
display: 'Printed?',
key: 'printed',
component: 'checkbox',
disabled: () => false,
},
gloss: {
display: 'Gloss Finish',
key: 'gloss',
component: 'checkbox',
disabled: state => !state.printed || !state.clearwater,
},
};
I have a working example answering a similar problem, please, have a look. The whole logic is done in redux:
Want to uncheck the node of the tree structure in React JS

React - Reset State stored from axios fetch

I am trying to reset the state for an object stored in my users array on click with handleDelete after I remove from the database. However, my state is not changing. I am able to log the current user with console.log('found: ' + this.state.users[i]). Basically, I have a table populated from my API and am trying to remove the row for the state without refreshing the page, but the state is not updating.
The constructor where my initial state is stored:
constructor(props) {
super(props);
this.state = {
users: []
}
this.handleDelete = this.handleDelete.bind(this);
};
Grabbing the API on mount:
componentDidMount() {
fetch('/myAPI')
.then(res => res.json())
.then(users => this.setState({ users }));
}
Mapping over data stored in state from fetch
render() {
return (
<tbody>
{this.state.users.map(user =>
<tr key={user.uniqueid}>
<td>{user.name}</td>
<td>{user.versions}</td>
<td>{user.type}</td>
<td>{user.hours}</td>
<td>{user.refresh}</td>
<td>{user.uniqueid}</td>
<td>{user.date}</td>
<td><Button onClick={this.handleDelete} data-id={user.uniqueid}><FaTrashO /></Button></td>
</tr>
)}
</tbody>
);
}
delete handler where I am TRYING to reset state for :
handleDelete(e) {
let dataId = e.target.getAttribute('data-id');
axios({
method: 'delete',
responseType: 'json',
url: '/myAPI',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Methods': "GET,HEAD,OPTIONS,POST,PUT"
},
data: { _id: dataId }
})
.then((response) => {
console.log(dataId + ' deleted with axios')
for (let i = 0; i < this.state.users.length; i++){
if (dataId === this.state.users[i]._id) {
let currentObj = this.state.users[i];
console.log('found: ' + this.state.users[i])
this.setState((prevState) => {
currentObj._id = ''
currentObj.date = '',
currentObj.hours = '',
currentObj.name = '',
currentObj.refresh = '',
currentObj.type = '',
currentObj.uniqueid = '',
currentObj.versions = ''
});
}
}
})
.catch((err) => {
throw err;
})
}
Example of what im calling from my API:
[
{
_id: "XJAbmHCX",
name: "an_example_2",
type: "B",
versions: "10",
hours: "10",
refresh: "Yes",
uniqueid: "XJAbmHCX",
date: "2018/01/08",
__v: 0
},
{
_id: "TOoIi7xS",
name: "test",
type: "A",
versions: "10",
hours: "10",
refresh: "Yes",
uniqueid: "TOoIi7xS",
date: "2018/01/09",
__v: 0
},
{
_id: "oeaigjesroigj",
name: "an_example_2_1",
type: "B",
versions: "10",
hours: "10",
refresh: "Yes",
uniqueid: "oeaigjesroigj",
date: "2018/01/08",
__v: 0
}
]
In the for loop of handleDelete, I simply sliced the user adn returned every object without the current ID to the state
for (let i = 0; i < this.state.users.length; i++){
if (dataId === this.state.users[i]._id) {
let users = this.state.users.slice();
users = users.filter(u => { return u._id !== dataId; });
this.setState({ users: users });
}
}

Categories

Resources