ReactJS: TypeError: Cannot read property 'name' of undefined
ReactJS: TypeError: Cannot read property 'name' of undefined
Working with ReactJS, Redux and Firestore I get an error when creating a new record. However I do not understand the reason as I get the updated information correctly in Redux but after creating the record and returning to see all the records I get the error:
TypeError: Cannot read property 'name' of undefined
If I access to visualize the records everything is fine the problem is when I generate a new record and return to visualize all.
My jSON response is like:
1:
data: email: "mail@hotmail.com", lastName: "Asdasd", name: "Oscar"
uid: "2ts2DopIoXoiMVJ6lMKi"
When I back to get all the records and do a console.log(this.props.clients) return this:
0:DocumentReference
firestore:
Firestore _queue: AsyncQueue, INTERNAL: …, _config: FirestoreConfig, _databaseId: DatabaseId, _dataConverter: UserDataConverter, …
id:(...)
parent:(...)
path:(...)
_firestoreClient:FirestoreClient platform: BrowserPlatform, databaseInfo: DatabaseInfo, credentials: FirebaseCredentialsProvider, asyncQueue: AsyncQueue, clientId: "BGuRUAvN7ZQxmmNEZmbx", …
_key:DocumentKey path: ResourcePath
__proto__:Object
This is my code:
Action: Get data from Firestore
export const getFromFirestore= () => async dispatch =>
let res = ;
await db.collection('users').get().then((snapShot) =>
snapShot.docs.map( doc =>
res.push( uid: doc.id, data: doc.data());
)
, error =>
console.log(error)
);
dispatch(
type: GET_CLIENTS,
payload:res
);
Reducer:
case GET_CLIENTS:
return
...state,
clientsFirestore: action.payload
;
Clients Component Show data from Firestore:
class Clients extends Component
componentDidMount()
this.props.getFromFirestore();
;
deleteClient = (id) =>
this.props.deleteFirestore(id);
render()
const clients = this.props;
return (
<React.Fragment>
<h1 className="display-4 mb-2">
<span className="text-danger">Clients</span>
</h1>
<table className="highlight centered">
<thead>
<tr>
<th>Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
clients && clients !== undefined ? clients.map((client, key) => (
<Client
key=key
id=client.uid
name=client.data.name
lastName=client.data.lastName
email=client.data.email
deleteClient=this.deleteClient
/>
)): null
</table>
</React.Fragment>
);
Clients.propTypes =
clients: PropTypes.array.isRequired,
const mapStateToProps = (state) => (
clients: state.clients.clientsFirestore
);
export default connect( mapStateToProps, getFromFirestore, deleteFirestore )(Clients);
Thanks!
name=client.data.name
client.data
name
data
@KarenGrigoryan I think the problem is that when I add a new firestore record, the first element of the different array returns something like:
0:DocumentReference firestore: Firestore _queue: AsyncQueue, INTERNAL: …, _config: FirestoreConfig, _databaseId: DatabaseId, _dataConverter: UserDataConverter, … id:(...) whrn my array of objects is like: 1: data: email: "mail@hotmail.com", lastName: "Asdasd", name: "Oscar" uid: "2ts2DopIoXoiMVJ6lMKi" But I dont know how get the data– OscarDev
Aug 26 at 8:31
0:DocumentReference firestore: Firestore _queue: AsyncQueue, INTERNAL: …, _config: FirestoreConfig, _databaseId: DatabaseId, _dataConverter: UserDataConverter, … id:(...) whrn my array of objects is like: 1: data: email: "mail@hotmail.com", lastName: "Asdasd", name: "Oscar" uid: "2ts2DopIoXoiMVJ6lMKi"
4 Answers
4
In Map function may be data property is undefined hence name property on data object throws TypeError: Cannot read property 'name' of undefined
Check data property has name property available before passing to <Client /> element.
TypeError: Cannot read property 'name' of undefined
<Client />
<Client
key=key
id=client.uid
name=typeof client.data.name !== 'undefined' && client.data.name
lastName=client.data.lastName
email=client.data.email
deleteClient=this.deleteClient
/>
Yep. The property 'name' its available but only when I access to view the records without adding any new
– OscarDev
Aug 26 at 8:19
I think some records don't have a name property. Can you check all records have name property? In loop iteration, name property is undefined on the data object.
– Sagar Gavhane
Aug 26 at 8:21
I think the problem is that when I add a new firestore record, the first element of the different array returns something like:
0:DocumentReference firestore: Firestore _queue: AsyncQueue, INTERNAL: …, _config: FirestoreConfig, _databaseId: DatabaseId, _dataConverter: UserDataConverter, … id:(...) whrn my array of objects is like: 1: data: email: "mail@hotmail.com", lastName: "Asdasd", name: "Oscar" uid: "2ts2DopIoXoiMVJ6lMKi"– OscarDev
Aug 26 at 8:25
0:DocumentReference firestore: Firestore _queue: AsyncQueue, INTERNAL: …, _config: FirestoreConfig, _databaseId: DatabaseId, _dataConverter: UserDataConverter, … id:(...)
1: data: email: "mail@hotmail.com", lastName: "Asdasd", name: "Oscar" uid: "2ts2DopIoXoiMVJ6lMKi"
Before returning, add an if query to check if the clients are fetched, then only map function will be able to use the inner object of client. Add a if (client === null) return <text>loading</text> or something to avoid the fetching error which will return undefined for a nested object.
Edit : in mapStateToProps define clients asclients : this.state.clients
if (client === null) return <text>loading</text>
mapStateToProps
clients : this.state.clients
Thanks. I added
clients && clients !== undefined ? clients.map((client, key)... but the problem persist. :(– OscarDev
Aug 26 at 8:20
clients && clients !== undefined ? clients.map((client, key)...
Where is your index.js for reducer? Have you connected the reducer to application state via
combinereducers?– Sanchit Bhatnagar
Aug 26 at 9:06
combinereducers
You should also check whether the clients and client are undefined or not and only then do map and if you really have property called name
Check below code
clients && clients != undefined ? clients.map((client, key) => (
client && client != undefined && client.data && (<Client
key=key
id=client.uid && client.uid
name=client.data.name && client.data.name
lastName=client.data.lastName && client.data.lastName
email=client.data.email && client.data.email
deleteClient=this.deleteClient
/>)
)): null
PS:- When you post these type of questions try to post the json data as well to find resolution quickly
Thanks. I tried your solution but the problem persist :/
– OscarDev
Aug 26 at 8:08
okey post you json data as well i.e., this.props.clients. Perhaps the name property doesn't exist in one of the object in this.props.clients
– Think-Twice
Aug 26 at 8:08
is that array of objects or only one object?
– Think-Twice
Aug 26 at 8:21
Thanks. Is an array of objects since I get a get of all the information in firestore.
– OscarDev
Aug 26 at 8:22
I updated my code. Give a try now
– Think-Twice
Aug 26 at 8:24
Solution:
export const addToFirestore = (client) => async dispatch =>
let res =
id:'',
data:
name:'',
lastName:'',
email:''
;
await db.collection("users").add(
name: client.name,
lastName: client.lastName,
email: client.email,
)
.then(function(docRef)
res.id = docRef.id;
res.data.name = client.name;
res.data.lastName = client.lastName;
res.data.email = client.email;
)
.catch(function(error)
console.error("Error adding document: ", error);
);
dispatch(
type: ADD_CLIENT,
payload:res
);
;
create an object since the answer of firestore only brings us the ID :|
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
based on your example the only suggestion is that in
name=client.data.nameclient.datais undefined, thus you have to check whether you accessnamecorrectly, or maybe even the wholedataobject is not needed– Karen Grigoryan
Aug 26 at 8:11