Objects are not valid as a React child. If you meant to render a collection of children, use an array - javascript

i want to render an email of all the users for testing purpose, In fact i have done that using this method. --- {dataFromApi.map((item, i) => {item.email})} but still it didn't work
const [dataFromApi, setDataFromApi] = useState([]);
const URL = 'http://localhost:5000/users'
const requestOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
}
const submit = () => {
const data = fetch(URL, requestOptions);
data.then( (userdata) => {
return userdata.json();
}).then( (data) => {
setDataFromApi(data[0]);
}).catch( (err) => {
console.log(err);
})
}
return (
<div className="login">
<h1 className="loginTitle">Choose a Login Method</h1>
<p>{dataFromApi}</p>
<div className="wrapper">
.
.
.
.
.
here is the API response
[
{
"id": 1,
"email": "test1234#gm.com",
"password": null
},
{
"id": 2,
"email": null,
"password": null
},
{
"id": 3,
"email": "test#123.com",
"password": "12345678"
},
{
"id": 4,
"email": "test#231.com",
"password": "12345678"
},
{
"id": 5,
"email": "test#231.com",
"password": "12345678"
},
{
"id": 6,
"email": "test#231.com",
"password": "12345678"
},
{
"id": 7,
"email": "NEWtest#231.com",
"password": "123"
}
]
but getting this error
react_devtools_backend.js:4012 The above error occurred in the component:
and
react-dom.development.js:14887 Uncaught Error: Objects are not valid as a React child (found: object with keys {id, email, password}). If you meant to render a collection of children, use an array instead.

Like Adam said in the comments, you are trying to pack a collection of things into a tag meant for a single thing. You should iterate over the list rendering a thing for each item.
{dataFromApi.map((item, i) => <p key={i}>{item.email}</p>)}

I got the answer why i'm not getting the expected output because in this code
const submit = () => {
const data = fetch(URL, requestOptions);
data.then( (userdata) => {
return userdata.json();
}).then( (data) => {
setDataFromApi(data[0]); // this will store only one object into an array
}).catch( (err) => {
console.log(err);
})
}
here setDataFromApi(data[0]) will store only 1 object and to access the email from the object, we have to use only dataFromApi.email else dataFromApi will give only object which we can't render so that's why it is giving an error.

Related

Trying to grab the correct post id from API in order to send message to only that post

In React Javascript - how would I send a message to a post with a specific id? Here's a sample object:
{
"success": true,
"error": null,
"data": {
"post": {
"location": "Bronx, NY",
"willDeliver": false,
"messages": [],
"active": true,
"_id": "5e8d1bd48829fb0017d2233b",
"title": "Schwinn Bicycle",
"price": "3.88",
"description": "This is a 19 speed bicycle, barely used.",
"author": {
"_id": "5e8d1a02829c8e0017c20b55",
"username": "joe1234"
},
"createdAt": "2020-04-08T00:33:24.157Z",
"updatedAt": "2020-04-08T00:33:24.157Z",
"__v": 0,
"isAuthor": true
}
}
}
I must be grabbing the id incorrectly because the message isn't sending to the right post.
I have a useState initialized with an empty string to store the post id so I can pass it into the fetch URL request.
const [postId, setPostId] = useState("");
const response = await fetch(`${API_URL}/posts/${id}/messages`
Here's the code I have so far
const sendMessage = async (token, id, content) => {
try {
const response = await fetch(`${API_URL}/posts/${id}/messages`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
message: {
content: content,
},
}),
});
const data = await response.json();
alert("message successfully sent");
return data;
} catch (err) {
console.error(err);
}
};
<form
name="message"
onSubmit={(event) => {
event.preventDefault();
posts.map((post) => {
setPostId(post._id);
});
}}
<label htmlFor="content">Content: </label>
<input
type="text"
name="content"
value={messageContent}
required
onChange={(event) => {
setMessageContent(event.target.value);
}}
/>
<button
onClick={() => {
sendMessage(token, postId, messageContent);
}}
>
Send
</button>
Thanks for any hints or help!

Modifying localStorage gives A cross-origin error

I'm making a web application using reactjs, and when development is suddenly this error appears:"A cross-origin error was thrown. React doesn't have access to the actual error object in development".I AuthContext witch gives user data to localStorage :
const AuthProvider = ({ children }) => {
const token = localStorage.getItem("token");
const userInfo = localStorage.getItem("userInfo");
const expiresAt = localStorage.getItem("expiresAt");
const [authState, setAuthState] = useState({
token,
expiresAt,
userInfo: userInfo ? JSON.parse(userInfo) : {},
});
const setAuthInfo = ({ token, userInfo, expiresAt }) => {
localStorage.setItem("token", token);
localStorage.setItem("userInfo", JSON.stringify(userInfo));
localStorage.setItem("expiresAt", expiresAt);
setAuthState({
token,
userInfo,
expiresAt,
});
};
Unfortunately i have a problem with updating user details.
In context i made another function:
Edit: I forgot to write that after the function is executed userDetails changes to undefined so I get a cross-origin error
const setUserInfo = ({ userInfo }) => {
localStorage.removeItem("userInfo");
localStorage.setItem("userInfo", JSON.stringify(userInfo));
setAuthState({
userInfo,
});
};
I have rest-api route to update-details , exemplary response:
{
"success": true,
"user": {
"role": role,
"_id": id,
"username": name,
"email": email,
"createdAd": createdAt,
"__v": 0
}
}
And user rest-api response when user login, example:
{
"success": true,
"token": token,
"expiresAt": expiresAt,
"userInfo": {
"role": role,
"_id": id,
"username": name,
"email": email,
"_id": id
}
}
Updating details working when i call it but after i get cross site error.
And heres Submit function
const handleUpdate = async (info) => {
setError("");
setLoading(true);
try {
const { data } = await fetchContext.authAxios.put(
"http://localhost:5000/api/v1/auth/update-details",
info
);
const user = data.user;
console.log(user);
auth.setUserState(data);
setError(null);
setLoading(false);
} catch (err) {
setLoading(false);
// const { data } = err.response;
// setError(data.error);
console.log(err);
}
};
Ok i dumb
const setUserInfo = ({ userInfo }) => {};
should be
const setUserInfo = ( userInfo ) => {};

fetch() api method POST sends to many data

I have problem with sending data via POST method in fetch(). So the problem is that from this >> body: JSON.stringify({ id: uuid(), name, password }) it sends couple of times almost the same data (i receive unique id, and diplicated name and password). In the othet words: with one form submission, I've got few objects with differnt id, and same name and password. Code:
const handleSubmit = e => {
e.preventDefault();
users.map(user =>
user.name !== name && name.length >= 3 && password.length >= 5
? fetch('http://localhost:3003/users', {
method: 'POST',
body: JSON.stringify({ id: uuid(), name, password }),
headers: {
'Content-Type': 'application/json'
}
})
.then(res => {
if (res.ok) {
return res.json();
}
throw new Error('Error');
})
.then(c => setUser([...users, c]))
.then(errorUserChange(false))
: errorUserChange(true)
);
};
db.json:
{
"users": [
{
"id": "c1a10ab0-24c7-11ea-af77-3b28fe4ea407",
"name": "cccccc",
"password": "cccccc"
},
{
"id": "cbf73890-24c7-11ea-af77-3b28fe4ea407",
"name": "kkkkkkk",
"password": "kkkkk"
},
{
"id": "cbf786b0-24c7-11ea-af77-3b28fe4ea407",
"name": "kkkkkkk",
"password": "kkkkk"
}
]
}
Of course I know that's not the best way to hold password, I'm just practicing json server and fetch().
Thanks for any help!

How can I get the same content in my react native app as in my postman GET?

I'm communicating with a REST server, which should return ( and this is what I get when I use Postman to request it):
{
"organizer": "Fontysgroup2",
"eventStart": "2019-11-25T11:00:00Z",
"eventStop": "2019-11-25T11:00:00Z",
"room": {
"roomName": "Test Room",
"roomEmail": null,
"password": null
}
},
{
"organizer": "Fontysgroup2",
"eventStart": "2019-11-25T11:00:00Z",
"eventStop": "2019-11-25T11:00:00Z",
"room": {
"roomName": "Test Room",
"roomEmail": null,
"password": null
}
}
]
but this block of code of mine :
await fetch('https://gitroom-backend.azurewebsites.net/api/Event', {
headers: {
Authorization: 'Bearer eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIs',
}
})
.then(res => {
console.log("content"+JSON.stringify(res))
})
}
is returning:
content{"type":"default","status":200,"ok":true,"headers":{"map":{"cache-control":"public, max-age=0","date":"Mon, 25 Nov 2019 13:14:09 GMT","set-cookie":"ARRAffinity=84e8f0e39af3bde1a8c7117e525b046a8722dc904bb8684ace19b555cc8f3590;Path=/;HttpOnly;Domain=gitroom-backend.azurewebsites.net","x-powered-by":"ASP.NET","request-context":"appId=cid-v1:65c12a05-4adc-4521-b71d-69ccdcb78d9f","server":"Microsoft-IIS/10.0","vary":"Accept-Encoding","content-type":"application/json; charset=utf-8","transfer-encoding":"chunked"}},"url":"https://gitroom-backend.azurewebsites.net/api/Event","_bodyInit":{"_data":{"size":331,"offset":0,"blobId":"7592c623-fb09-415e-92f7-a97e75b08d37"}},"_bodyBlob":{"_data":{"size":331,"offset":0,"blobId":"7592c623-fb09-415e-92f7-a97e75b08d37"}}}
How can I access the actual content that I want and which Postman is giving me?
EDIT:
MY Postman:
fetchData = async () => {
const response = await fetch(
"YOUR_URL"
);
const json = await response.json();
}
Now render items iterative using constructor of your data set.
and call in your view by,
{item.YOUR_KEY}

How to do multiple nested query (GET request) with GraphQL Yoga?

How can I do multiple nested query using GraphQL Yoga?
This is my data
{
"user": [{
"id": 1,
"name": "Thomas",
"comment_id": [1, 2, 3]
},
{
"id": 2,
"name": "Riza",
"comment_id": [4, 5, 6]
}
],
"comment": [{
"id": 1,
"body": "comment 1"
},
{
"id": 2,
"body": "comment 2"
},
{
"id": 3,
"body": "comment 3"
}
]
}
The scenario is that I want to query a particular user with all its comments, but the user only stores the comment ids.
This is my code
const { GraphQLServer } = require('graphql-yoga');
const axios = require('axios');
const typeDefs = `
type Query {
user(id: Int!): User
comment(id: Int!): Comment
}
type User {
id: Int
name: String
comment: [Comment]
}
type Comment {
id: Int
body: String
}
`;
const resolvers = {
Query: {
user(parent, args) {
return axios
.get(`http://localhost:3000/user/${args.id}`)
.then(res => res.data)
.catch(err => console.log(err));
},
comment(parent, args) {
return axios
.get(`http://localhost:3000/comment/${args.id}`)
.then(res => res.data)
.catch(err => console.log(err));
},
},
User: {
comment: parent =>
axios
.get(`http://localhost:3000/comment/${parent.comment_id}`)
.then(res => res.data)
.catch(err => console.log(err)),
},
};
const server = new GraphQLServer({ typeDefs, resolvers });
server.start(() => console.log('Server is running on localhost:4000'));
Desired Query
{
user(id: 1) {
id
name
comment {
id
body
}
}
}
But it returns not found, because the endpoint that the axios hit is http://localhost:3000/comment/1,2,3'
How can i make it return all user's comments?
Thanks guys!
Assuming that comments API /comment/:id accepts only single id, you would need to make one API call per comment ID (unless there is an API which takes multiple ID's and return their data) and then return response from comment field resolver of User type.
This is how resolver for comment field would look like in that case:
User: {
comment: parent => {
let results = await Promise.all(parent.comment_id.map((id) => axios.get(`http://localhost:3000/comment/${id}`)))
return results.map((result) => result.data)
}
}
Apparently I also found this other solution
User: {
comment: parent =>
parent.comment_id.map(id =>
axios.get(`http://localhost:3000/comment/${id}`).then(res => res.data)
),
},
Performance wise, which one do you think it's better?

Categories

Resources