Choose value relating to index in render function, React Native, ES6 - javascript

I have a simple video view and all I want to do is assign the volume props to a number however it's an array of videos and each video has a different volume, so I created an array based on the index of videos now I need each video to have it's specific volume
var arr = [{vol: 1}, {vol: 3}, {vol: 8}] //3 items in render
this.state = {
volVid: arr
}
render() {
return this.props.otherUsers.map(others =>
<View key={others.infinite}>
<Video
volume={this.state.volVid}
>
</Video>
</View>
);
}
I would have put a function inside the volume props however it gave an error of expecting a number and instead receiving a function, so is there a way to reach into the array and pull the specific video volume?
Expo video component being used here.

Based on the code provided, you can just add the index to the passed callback function and use that. So:
render() {
return this.props.otherUsers.map((others, index) =>
<View key={others.infinite}>
<Video
volume={(this.state.volVid[index]) ? this.state.volVid[index].vol : 1}
>
</Video>
</View>
);
}
Added a ternary check just in case otherUsers.length > arr.length

I think what you're trying to do is to refer to your volVid array through index prop on .map():
render() {
return this.props.otherUsers.map((others, index) => {
<View key={others.infinite}>
<Video
volume={this.state.volVid[index].vol}
>
</Video>
</View>
});
}

Related

Mapping through objects and render in React Native

I have a React Native project where i am getting object like the attached image. I need to map through them and render description and rate from them.
How can i acheive this. I have been trying with Object.keys but not been able to do it. Here's what i have tried. Don't know if it makes sense:
{Object.keys(myObject).map(function(key, index) {
return (
<Text>
{myObject.map((rate, description) => {
return (
rate,
description
)
})
</Text>
}
If you're just trying to map the rate and description, you don't need the second map -- you can just use the key to get the entry from the original object and then access its properties directly:
{Object.keys(myObject).map(key => {
const item = myObject[key];
return (<View>
<Text>{item.rate}</Text>
<Text>{item.description}</Text>
</View>
)})}
You can not use map on objects so try with bellow code
<>
{Object.keys(myObject).map((key, index)=>
<Text>{myObject[key].description}, {myObject[key].rate}</Text>
)
}
</>

React render quantity of components based on a numeric value

I want to pass in a value to a component and render multiple child components based on that value. e.g. if I pass in count={4} in props, then I want to render 4 <Icon/> components. If I pass in 5, I want to render 5, and so on.
At the moment, all I can think to do is to take the value and turn it into an array (i.e. do a for loop and push a placeholder element to an array with each iteration) and then do a map on that array. But that seems like overkill.
Is there a simple solution to this?
You can do it like this:
...
return(
Array.from({length: props.count}, () => <Icon />)
)
You're probably looking a way to map amount of children to be populated. Check this live example: https://snack.expo.io/#zvona/mapping-child-components
This is the core code from that example:
const Icon = ({index}) => (
<View><Text>{`Icon #${index + 1}`}</Text></View>
);
const Icons = ({count}) => (
Array.from({length: count}).map((_item, index) => <Icon index={index}/>)
)
const App = () => {
return (
<View style={styles.container}>
<Icons count={5} />
</View>
);
}
You can use a simple for loop for this
for(let i = 0; i < count ; i++){
return <Icon />
}
If this doesn't work, you can do the following. It's a bit modern es6 function. Try this..
{[...Array(count)].map((x, i) =>
<Icon key={i} />
)}

How can I remove the element that is clicked, instead of all items being deleted except the item clicked?

This is from a react native tutorial -> https://www.youtube.com/watch?v=qSRrxpdMpVc
The app is for putting down what your 'course goals' are. It's basically just a ToDo list. You can add goals and remove them.
To try and get my head around it I thought I'd try and do the 'delete' code myself. I want to know how I can make my method work:
export default function App() {
const [courseGoals, setCourseGoals] = useState([]);
function addGoalHandler(goalTitle) {
setCourseGoals([goalTitle, ...courseGoals]);
}
function removeGoalHandler(index) {
console.log(index)
setCourseGoals(courseGoals.splice(index, 1));
}
return (
<View style={styles.screen}>
<GoalInput onAddGoal={addGoalHandler}/>
<ScrollView>
{courseGoals.map((goal, index) => <GoalItem onDelete={() => removeGoalHandler(index)} title={goal} key={index}/>)}
</ScrollView>
</View>
);
}
What I thought would happen on line 10 is that the courseGoals array would be set to courseGoals minus the spliced element. Instead, I have discovered that splice actually returns the deleted item. How can I fix this? Is there no way to just get courseGoals.splice() to return the array without the spliced element?
You can do it by using slice:
function removeGoalHandler(index) {
console.log(index);
setCourseGoals([...courseGoals.slice(0, index), ...courseGoals.slice(index + 1)]);
}
or with splice:
function removeGoalHandler(index) {
console.log(index);
const courseGoalsCopy = [...courseGoals];
courseGoalsCopy.splice(index, 1);
setCourseGoals(courseGoalsCopy);
}

How to filter an array by ignoring elements with undefined properties?

I am trying to map image URLs to an avatar component. The data I am using is coming from an Google Books API. The data resource is an array of objects (books). Some objects have missing values for the "thumbnail" field I am targeting.
I want to IGNORE these objects if they do not have a value for "thumbnail" and continue mapping through the array.
I am using React Native and Expo
I have tried various methods mentioned on Stack Overflow, including array.filter() with logic on my data before array.map(). None of the recommended solutions have worked.
The error I recieve is:
TypeError: TypeError: undefined is not an object(evaluating 'url.volumeInfo.imageLink.thumbnail')
It appears I can't even have that path inside of an "if" statement, which is strange to me - because even if that value is undefined, why should that matter?
renderCategory() {
if (this.props.adventure.payload[0]) {
const fetched_Book = this.props.adventure.payload;
const filteredThumbnails = fetched_Book.filter(url =>{
// The console log below shows 4 urls before it fails)
console.log('URL', url.volumeInfo.imageLinks.thumbnail)
if(typeof url.volumeInfo.imageLinks.thumbnail === "undefined"){
return false
}
else return true;
})
const allThumbnails= filteredThumbnails.map(book => book.volumeInfo.imageLinks.thumbnail);
return (
<>
<View style={styles.thumbnailContainer}>
{
allThumbnails.map((l, i) =>
<Avatar
key={i}
size="large"
source={{ uri: l }}
style={styles.thumbNail}
onPress={() => this.onSelectedBook(fetched_Book, i)}
/>
)
}
</View>
</>
)
}
else return ''
}
The expected output is a new, filtered array of objects, that can then be mapped into my Avatar Component.
This error means that some part of path to thumbnail does not exist so you need to check if each part of that path exists:
const filteredThumbnails = fetched_Book
.filter(url => !!url && !!url.volumeInfo && !!url.volumeInfo.imageLinks && typeof url.volumeInfo.imageLinks.thumbnail === 'undefined')

javascript React Native

Hi (Sorry for my english)
I have a problem, I consume a service that bring me a buttons array for a dynamic menu. This array I want to put in the screen, like button have a id for a action in specific.
Code
var sizes = []
for (var i = 0; i < this.state.tallas.length; i++) {
sizes.push(
<TouchableOpacity style={[styles.clothingSizeItem, this.state.idSize === this.state.tallas[i].id ? styles.activeClothingSizeItem:null]}
onPress={() => this.fetchSizeData(this.state.tallas[i].id)}>
<Text style={this.state.idSize === this.state.tallas[i].id ? styles.activeSizeText:null}>
{this.state.tallas[i].name}
</Text>
</TouchableOpacity>
);
}
View
render() {
return(
{sizes}
)
}
The problem is when I press a button from my dinamic menu, the button call a function that receive a parameter, but this parameter comes from service array. So I use "i" param from for, but this variable ("i") can't found after that the screen was rendered.
Screen Shot
error screen
Gracias!
You can use Array#map instead of a for loop:
const sizes = this.state.tallas.map(item => (
<TouchableOpacity style={[styles.clothingSizeItem, this.state.idSize === item.id ? styles.activeClothingSizeItem:null]}
onPress={() => this.fetchSizeData(item.id)}>
<Text style={this.state.idSize === item.id ? styles.activeSizeText:null}>
{item.name}
</Text>
</TouchableOpacity>
);
The reason the for loop doesn't work here is that the index variable i is incremented on every iteration of the loop, so by the time the callback ends up being called (long after the loop has completed), the value i is always it's final value (same as tallas.length).

Categories

Resources