Extract key:value pair from an object sent to backend - javascript

I am trying to use the value from an object. I don't need to use the 'key' part of the object. Also, I need to remove the curly brackets { } from around the object. How can I do so ?
I'm making a searchbar that sends data into backend, but I only need to use the 'value' part of the object. Perhaps I should use query strings for that ?
const handleClick = (e) => {
e.preventDefault() // stop page from refresh
if (setUserInput !== '') { // is searchbar isnt empty, then run the POST method to send
// data from {userInput} which is the searchbar
const options =
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({userInput}),
};
const response = fetch('http://localhost:3001/search', options);
console.log("search entered");
};
}
in the backend when I console.log the response it gives me
`"{ userInput: 'lollol' }"
and out of all of that I only need the 'lollol' part ( lollol is just an example, but whatever is typed into the searchbar will be shown instead of it ). As such:
const searchResult = req.body /// return lollol ✅
not
const searchResult = req.body /// return `"{ userInput: 'lollol' }" ❌
Should I use query strings to accomplish this, or is there a way to extract data from an object?

You don't need to stringify the object in the body. Replace
body: JSON.stringify({userInput}),
with
body: {userInput:userInput},
And then you can use it like req.body.userInput.
Hope, it helps!!

Related

Vue - InertiaJS: Enter Object not able

In my props, I pass the array "ticket_data" when loading the Vue component. Now I want to make a post to a controller using the Inertia form. This also works without problems.
My problem is, I can not access individual values from the array ...
My code:
let props = defineProps({
ticket_data: Object,
ticket_messages: Object,
});
let form = useForm({
text: '',
});
let submit = () => {
form
.transform((data) => ({
data,
ticket_id: props.ticket_data.ticket_id, // null
ticket_id: props.ticket_data, // gives all Data see Json
}))
.post('/account/user/support/ticket/send', {
preserveScroll: true,
onSuccess: () => form.reset('text'),
});
};
If I submit props.ticket_data individually, the following post arrives at my controller:
"ticket_id":[{"user_id":1,"ticket_id":5,"reference":"Testticket","state":0,"author":"Kevin Johnson","text":"..","created_at":"11/04/22 - 19:58"}]}
If the data arrives with "props.ticket_data", why can't I just access it with "props.ticket_data.ticket_id" ?
"props.ticket_data.[1]" doesn't work like that either....
Get a ticket by Id like this:
props.ticket_data.find(ticket => ticket.ticket_id === 5) // <-- ticket id

Pushing to an array is returning index rather then items (React)

I'm trying to add a new object to the end of an array that I'm dynamically fetching over my API. Users complete a form so the data is passed from the form to the state.
The initial first fetch is storing the original array to some react state which is fine, then at some point, a single object should be added to the end of the original array, so the whole array will contain the original data, plus the new object added.
Naturally, I'm trying to use array.push() to try and achieve this, but I keep getting the index rather than the data object.
// declare state will be an array
const [originalPages, setOriginalPages] = useState([]);
// Get all the existing data
loadInitialValues() {
return fetch(`example.com/api/collections/get/testing_features?token=${process.env.REACT_APP_API_KEY}`)
.then((res) => {
return res.json();
})
.then((res)=>{
// set state to be the whole array for this post
setOriginalPages(res.entries[4].pagebuild);
return res.entries[4].pagebuild[0].settings;
})
.catch((err)=>{
console.error(err);
})
}
At this point the data is all working completely fine, the collection of the new data from the forms works fine too. However, this is the point when the data goes to get posted back to update the API but just returns a number:
onSubmit(formData) {
// Dynamically hook all the newly collected form data to this new data object
let theData = {
component: 'page',
settings: {
title: formData.title,
pageOptions: {
pageSideImg: formData.pageOptions.pageSideImg,
isReversed: formData.pageOptions.isReversed,
paraGap: formData.pageOptions.paraGap,
paraFont: formData.pageOptions.paraFont,
},
pageNavigation: {
pageSlug: formData.pageNavigation.pageSlug,
nextPage: formData.pageNavigation.nextPage,
prevPage: formData.pageNavigation.prevPage,
},
globalOptions: {
projectName: formData.globalOptions.projectName,
transType: formData.globalOptions.transType,
menuTrans: formData.globalOptions.menuTrans,
},
blocks: formData.blocks
}
};
cms.alerts.info('Saving Content...');
return fetch(`example.com/api/collections/save/testing_features?token=${process.env.REACT_APP_API_KEY}`, {
method: 'post',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: {
// Only returning the array count as a number
pagebuild: originalPages.push(theData),
_id: "610963c235316625d1000023"
}
})
})
.then(response => response.json())
.catch((err) => {
cms.alerts.error('Error Saving Content');
console.log(err);
});
},
If anyone has any ideas as to why this is happening id greatly appreciate it!
For reference, I've checked here and maybe I should use spread instead?
The Array.push doesn't return the final array you would need, but the final length of modified array (that's why you thought it was an index).
Replace this string pagebuild: originalPages.push(theData), with this one:
pagebuild: [...originalPages, theData],
Of course, if you want to update the internal originalPages state value, call this within your onSubmit():
setOriginalPages(x => [...x, theData]);

Modify deeply nested data in Apollo client query result

I'm using #apollo/client to fetch data from Storyblok's API.
I want to iterate over all the fields in the returned data to potentially sanitize its content (it contains raw HTML). Because Apollo makes the result data immutable, I'm not able to do this:
const client = new ApolloClient({
uri: "https://gapi.storyblok.com/v1/api",
cache: new InMemoryCache(),
headers: {
token: "EXAMPLE",
},
});
function sanitizeFields(obj) {
for (const field of obj) {
if (field?.type === "custom-rich-text") {
field.content = sanitizeContent(field.content); // 💥 This generates an error because I'm trying to modify a read only object
}
if (Array.isArray(field) || isPlainObject(field)) {
sanitizeFields(field);
}
}
}
const postData = await client.query({ query: MY_QUERY });
sanitizeFields(postData?.data?.Page);
How can I modify deeply nested data returned by #apollo/client without knowing the particular field name beforehand?

React & Axios - Not receiving response data upon page refresh

Working on a project here and ran into an issue. I haven't had this problem before but now I do for some reason.
So I am making an GET request to ASOS API, but it is acting very strange. Some of these, such as name is received upon page refresh, but mainly the other things like information about the brand becomes undefined. Now, the brand is in another object inside of the API. But I have had other things at other parts of the page before that were also in objects. But I did not have any issue there.
Here is how the API call looks like:
And here is my code for the API fetch:
const FetchAPI = (props) => {
const [product, setProduct] = useState({});
const [brand, setBrand] = useState({});
const [price, setPrice] = useState({});
const [params, setParams] = useState({
id: "23363645",
lang: "en-US",
store: "US",
sizeSchema: "US",
currency: "USD",
});
useEffect(() => {
const options = {
method: "GET",
url: "https://asos2.p.rapidapi.com/products/v3/detail",
params: params,
headers: {
"x-rapidapi-key": "",
"x-rapidapi-host": "",
},
};
axios
.request(options)
.then(function (response) {
console.log(response.data);
setProduct(response.data);
setBrand(response.data.brand);
setPrice(response.data.price.current);
})
.catch(function (error) {
console.error(error);
});
}, []);
return (
<div>
<Product
name={product.name}
price={price.text}
brand={brand.description.replace( /(<([^>]+)>)/ig, '')}
/>
</div>
);
};
I am sending the data over to Product which is the product page of the item I am requesting. But whenever I refresh the page, I get TypeError: Cannot read property 'replace' of undefined. I did remove replace, and it worked fine. And if I placed replace back into the brand.description and saved, still worked fine. But on the page refresh, it crashes.
Is it perhaps trying to load my return before the useEffect? If so, how do I solve this?
I think the issue here is that while data from API is being fetched, brand.description is undefined and there is no replace method on undefined. You can either do this - >
<div>
<Product
name={product.name}
price={price.text}
brand={brand.description ? brand.description.replace( /(<([^>]+)>)/ig, '') : ""}
/>
</div>
or
const [brand, setBrand] = useState({ description: ""});
and keep the remaining code same.
First of all, unrelated to your question, you have many superfluous state variables. You have product which stores all the data of the product and then price and brand which stores subsets of the same data.
Consider using only the product state variable, or if you want to keep the names do something like
const price = product.price.current;
Second, your default value for brand is an empty object, meaning brand.description is undefined.
You can solve this with optional chaining like so:
<Product
name={product?.name}
price={price?.text}
brand={brand?.description?.replace( /(<([^>]+)>)/ig, '')}
/>
The useEffect hook gets called once the component is rendered so in this case initially when your API is not called your brand.description will be undefined and when you are trying to use replace on undefined the error is coming. So you can always add a check using optional chaining(?.) so even if we don't get the description in the brand it will not break the website and you should also use a loader till the API call is through.
<div>
<Product
name={product.name}
price={price.text}
brand={brand.description?.replace( /(<([^>]+)>)/ig, '')}
/>
</div>
useEffect gets called only after the component is rendered . So when the component is rendered for the first time you have the state brand as an empty object . So what you are trying to do is {}.description -> . This is undefined .
This is the reason why its a good practice to always have a loading state when the component is making an api call.
const [ loading, setLoading ] = useState(true);
const getProductDetails = async() => {
const options = {
method: "GET",
url: "https://asos2.p.rapidapi.com/products/v3/detail",
params: params,
headers: {
"x-rapidapi-key": "",
"x-rapidapi-host": "",
},
};
try {
const { data } = await axios.request(options);
setProduct(data);
setBrand(data.brand);
setPrice(data.price.current);
}
catch(error){
console.log(error)
} finally {
setLoading(false)
}
}
useEffect(() => {
getProductDetails();
}, []);
if(loading)
return <p> Loading ... </p>
return (
// return your JSX here
)

Is there a way to grab only a desired string from an object that contains an email? I need to catch only the string before the #

I try to extract only the username from the "userPrincipalName" and then concatenate it into the call of Axios as a parameter.
the "userPrincipalName" Contains email like this apple#foo.com and i need to concatenate only the "apple" ( i mean that I need just the string before the "#")
i dont understand what is my mistake on my split ..?
this is my example :
getData = () => {
const { userPrincipalName } = this.state.azureLoginObject;
this.setState({ isLoading: true, data: [] })
axios.get("https://rallycoding.herokuapp.com/api/music_albums",{ userPrincipalName }.split('#')[0])
.then(res => {
this.setState({
isLoading: false,
data: res.data
});
console.log(res.data);
});
}
assuming that "userPrincipalName" contains email "apple#foo.com" after
const { userPrincipalName } = this.state.azureLoginObject;
you can use the userPrincipalName as it is instead of putting it in { }.
axios.get("https://rallycoding.herokuapp.com/api/music_albums",userPrincipalName.split('#')[0])
It seems like you are using split method on object rather than on string. I have updated the. If doesnot helps you, can you please update the error.
axios.get("https://rallycoding.herokuapp.com/api/music_albums", userPrincipalName.split('#')[0])

Categories

Resources