Need SPLIT ARRAY for post in API - javascript

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

Related

TypeScript functional programming patterns for comfortable object construction?

I'm having a hard time finding examples (videos or blogs) of functional programming object construction patterns.
I recently encountered the below snipped builder pattern and I like the experience it provides for constructing an object with nesting. When it's a flatter object, I'd normally just use a simple object factory with an opts param to spread with defaults, but passing in a nested array of objects starts to feel messy.
Are there FP patterns that can help make composing an object with nesting like the below comfortable while allowing for calling some methods n times, such as addStringOption?
const data = new SlashCommandBuilder()
.setName('echo')
.setDescription('Replies with your input!')
.addStringOption(option =>
option.setName('input')
.setDescription('The input to echo back')
.setRequired(true)
)
.addStringOption(option =>
option.setName('category')
.setDescription('The gif category')
.setRequired(true)
.addChoices(
{ name: 'Funny', value: 'gif_funny' },
{ name: 'Meme', value: 'gif_meme' },
{ name: 'Movie', value: 'gif_movie' },
));
data ends up looking something like:
{
name: "echo",
description: "Replies with your input!",
options: [
{
name: "input",
description: "The input to echo back",
type: 7, // string option id
required: true,
choices: null,
},
{
name: "category",
description: "The gif category",
required: true,
type: 7,
choices: [
{ name: "Funny", value: "gif_funny" },
{ name: "Meme", value: "gif_meme" },
{ name: "Movie", value: "gif_movie" },
],
},
],
};
Below is what I'm playing around with. I'm still working on learning how to type them in TS so I'm sharing the JS.
Allowing for method chaining in the below snippet is maybe contorting FP too much make it like OOP, but I haven't found an alternative that makes construction flow nicely.
An alternative could be standalone builders each returning a callback that returns the updated state then pipe these builders together, but with some builders being callable n times it's hard to make and provide the pipe ahead of time and without the dot notation providing intellisense it seems harder to know what the available functions are to build with.
const buildCommand = () => {
// data separate from methods.
let command = {
permissions: ['admin'],
foo: 'bar',
options: [],
};
const builders = {
setGeneralCommandInfo: ({ name, description }) => {
command = { ...command, name, description };
// trying to avoid `this`
return builders;
},
setCommandPermissions: (...permissions) => {
command = { ...command, permissions };
return builders;
},
addStringOption: (callback) => {
const stringOption = callback(buildStringOption());
command = { ...command, options: [...command.options, stringOption] };
return builders;
},
// can validate here
build: () => command,
};
return builders;
};
const buildStringOption = () => {
let stringOption = {
choices: null,
type: 7,
};
const builders = {
setName: (name) => {
stringOption = { ...stringOption, name };
return builders;
},
setDescription: (description) => {
stringOption = { ...stringOption, description };
return builders;
},
addChoices: (choices) => {
stringOption = { ...stringOption, choices };
return builders;
},
build: () => stringOption,
};
return builders;
};
const command1 = buildCommand()
.setGeneralCommandInfo({ name: 'n1', description: 'd1' })
.setCommandPermissions('auditor', 'moderator')
.addStringOption((option) =>
option.setName('foo').setDescription('bar').build()
)
.addStringOption((option) =>
option
.setName('baz')
.setDescription('bax')
.addChoices([
{ name: 'Funny', value: 'gif_funny' },
{ name: 'Meme', value: 'gif_meme' },
])
.build()
)
.build();
console.log(command1);
Why not simply create and use data constructors?
const SlashCommand = (name, description, options) =>
({ name, description, options });
const StringOption = (name, description, required, type = 7, choices = null) =>
({ name, description, required, type, choices });
const Choice = (name, value) => ({ name, value });
const data = SlashCommand('echo', 'Replies with your input!', [
StringOption('input', 'The input to echo back', true),
StringOption('category', 'The gif category', true, undefined, [
Choice('Funny', 'gif_funny'),
Choice('Meme', 'gif_meme'),
Choice('Movie', 'gif_movie')
])
]);
console.log(data);
TypeScript Playground Example
You can't get more functional than this. Intellisense will also help you with the constructor arguments.

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)

In react How to split the handle change value in react

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
}
);

Create new object from array

I'm trying to create new object with different properties name from Array.
Array is:
profiles: Array(1)
0:
column:
name: "profileName"
title: "Profile name"
status: "Active"
I want to create new function that return object with two properties:
id: 'profileName',
profileStatus: 'Active'
The function that I have create is returning only one property as undefined undefined=undefined.
function getProfile(profiles) {
if (!profiles.length) return undefined;
return profiles.reduce((obj, profile) => {
console.log('profiles', profile);
return ({
...obj,
id: profile.column.name,
profileStatus: profile.status,
});
}, {});
}
The function getProfile is taking as input array 'profiles' from outside,
I've just tested here and this seems to be working actually
const getProfile1 = (p) => p.reduce((obj, profile) =>({
...obj,
id: profile.column.name,
profileStatus: profile.status,
}), {});
You can use map as an alternative.
var profiles = [{"column":{"name": "profileName3","title": "3Profile name"},"status": "Active"},{"column":{"name": "profileName","title": "Profile name"},"status": "Active"}];
function getProfile(profiles) {
if (!profiles.length) return undefined;
return profiles.map(function(profile,v){
return {id:profile.column.name,profileStatus: profile.status};
});
}
console.log(getProfile(profiles));
Whenever I use reduce in this way, I usually index the final object by some sort of an id. As noted in another answer, you could use map in this situation as well. If you really want your final data structure to be an object, however, you could do something like this:
/**
* returns object indexed by profile id
*/
const formatProfiles = (profiles) => {
return profiles.reduce((obj, profile) => {
return {
...obj,
[profile.id]: {
id: profile.column.name,
profileStatus: profile.status,
}
};
}, {});
};
const profiles = [
{
id: 0,
status: 'active',
column: {
name: "profile_name_1",
title: "profile_title_1",
},
},
{
id: 1,
status: 'inactive',
column: {
name: "profile_name_2",
title: "profile_title_2",
}
}
];
const result = formatProfiles(profiles);
/**
* Result would look like this:
*/
// {
// '0': { id: 'profile_name_1', profileStatus: 'active' },
// '1': { id: 'profile_name_2', profileStatus: 'inactive' }
// }

Update object value in array React hooks way

How would I update a title of the specific id with hooks state setup. Here:
const NotesContainer = ({
}) => {
const [notesDummyData, setNotesDummyData] = useState([
{
id: '5',
title: 'Sauna',
},
{
id: '7',
title: 'Finland',
},
]);
const onChangeItemName = (newTitle, oldTitle, itemId) => {
//Update a new title here for id 7
};
Could not find any example for setState hooks.
Just map through the items and if the id is equal to the selected id you modify only the value:
const onChangeItemName = (newTitle, oldTitle, itemId) => {
setNotesDummyData(notesDummyData.map(x => {
if(x.id !== itemId) return x
return {...x, title: newTitle}
}))
}
You can use Array.map(). For each item check if the id is equal to itemId. If it this, spread the item, and replace the title. If not, return the original item:
const onChangeItemName = (title, itemId) => {
setNotesDummyData(notesDummyData.map(o => o.id === itemId ? ({
...o,
title
}) : o));
};
It's easy to update data using React Hook, but there is not working setState(), so there will be working [notThis, thisOne(setNotesDummyDate)] to update your data.
const [notesDummyData, setNotesDummyData] = useState([
{
id: '5',
title: 'Sauna',
},
{
id: '7',
title: 'Finland',
},
]);
Using React Hook method to Update data:
const onChangeItemName = (newTitle, oldTitle, itemId) => {
setNotesDummyDate = useState([
{
id: itemId, // Update
title: newTitle,
},
{
id: itemId, // Update
title: newTitle,
},
]);
}
Still Curious, study here about useState()
Cheer you!

Categories

Resources