Reputation: 133
In a React project, I want to dynamically access an object property name using a string variable I pass through props. I am able to pass a value as string; however, when I try to use it to access the object property it doesn't work.
Here's an example:
const passedField = 'title'; // this comes from props
const book = { title: 'Sample title', content : 'some content' };
book.passedField; // returns undefined
I access title like this book.title
I want to access it like book.passedField
but I get undefined on console.
How can I achieve this?
Upvotes: 0
Views: 14239
Reputation: 3604
What you're using is called a dot notation
property accessor. What you need to use is a bracket notation
property accessor.
book.title
and book['title']
are the same, which means you can assign title
to a variable, and use the variable name instead like this.
const passedField = 'title';
book[passedField]; // same as book['title']
You might only be familiar with bracket notation
with Arrays, like myArray[0]
, but they work with Objects too! (because Arrays in JavaScript are actually objects)
const books = [
{
title: 'The Art of War',
contents: 'An ancient Chinese military treatise dating from the Spring and Autumn Period'
},
{
title: 'Winnie the Pooh',
contents: 'Pooh is naive and slow-witted, but he is also friendly, thoughtful, and steadfast.'
}
]
class Book extends React.Component {
constructor(props) {
super(props);
this.findBookByFilter = this.findBookByFilter.bind(this);
}
findBookByFilter() {
let result = null
if (books) {
const {passedFilterField, filterText} = this.props;
result = books.filter(book => {
return book[passedFilterField].toLowerCase().includes(filterText.toLowerCase());
}).map(book => <p>{book.title}</p>)
}
return result;
}
render () {
return this.findBookByFilter();
}
}
class App extends React.Component {
render() {
return (
<Book
passedFilterField='contents'
filterText='thoughtful'
/>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
{book && book.filter}
logic to a function called findBookByFilter
includes
instead of indexOf
in the filter
this.props
<Link />
for demo purposes.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
Upvotes: 4
Reputation: 12874
book.passedField
will be returning undefined because there is no passedField
in book
. Instead use bracket notation as below
const book = { title: 'abc', pages: 350 };
const passedField = 'pages';
console.log(book[passedField])
Upvotes: 4