Home > Enterprise >  Deleting wrong image from array
Deleting wrong image from array

Time:05-03

I'm trying to delete selected image from an array of images and yet only the first image on the list gets deleted whenever i tap any other image to delete. This is surprising cause i implemented the same method when generating a list in the same screen and it deletes the correct list item each time i tap on it to delete.

Here is all the code in the file excluding cascading styles. Its a lot but i Hope this helps.

const AddPost = () => {
  
  const navigation = useNavigation();
  // Thumbnail State
  const [thumbnail, setThumbnail] = useState(null);
  // Media State
  const [media, setMedia] = useState([]);
  // Details State
  const [title, setTitle] = useState('');
  const [category, setCategory] = useState('');
  const [caption, setCaption] = useState('');
  const [price, setPrice] = useState('');
  const [details, setDetails] = useState(false);
  // Store State
  const [itemName, setItemName] = useState('');
  const [itemPrice, setItemPrice] = useState('');
  const [photoArray, setPhotoArray] = useState([]);
  const [storeItems, setStoreItems] = useState([]);

  const width = useWindowDimensions().width;

  const numColumns = Math.ceil(width / 120);

  const pickThumbnail = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      quality: 0.5,
    });

    if (!result.cancelled) {
        setThumbnail(result.uri);
    }
  };

  const pickMedia = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      quality: 0.2,
    });

    if (!result.cancelled) {
        setMedia([...media, result.uri]);
    }
  };
  
  const deleteMedia = (index) => {
      let removeMedia = [...media];
      removeMedia.splice(index, 1);
      setMedia(removeMedia)
      console.log(index)
  };

  const addDetailItem = () => {
    if (title == '' || category == '' || caption == '' || price == '') {
        Alert.alert('Error', 'Please fill in the item detail.')
    } else {
        Keyboard.dismiss();
        setDetails(true);
        detailsRef?.current?.close();
    };
  };

  const detailsRef = useRef(null);

  const toggleModal = () => {
      detailsRef?.current?.present();
  }

  const toggleModalClose = () => {
    detailsRef?.current?.close();
  }

  const addItem = {
    id: Math.floor(Math.random() * 11),
    itemName: itemName, 
    itemPrice: itemPrice,
    photo: photoArray
  };

  const storeRef = useRef(null);

  const toggleStoreModal = () => {
      storeRef?.current?.present();
  }

  const toggleStoreModalClose = () => {
    storeRef?.current?.close();
  }

  const addStoreItem = () => {
      if (itemName == '' || itemPrice == '') {
          Alert.alert('Error', 'Please fill in the item detail.')
      } else {
          Keyboard.dismiss();
          setStoreItems([...storeItems, addItem]);
          setItemName(null);
          setItemPrice(null);
          setPhotoArray([]);
      };
  };

  const deleteItem = (index) => {
      let removeItem = [...storeItems];
      removeItem.splice(index, 1);
      setStoreItems(removeItem)
  };

  const pickPhoto = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      quality: 0.2,
    });

    if (!result.cancelled) {
        setPhotoArray([...photoArray, result.uri]);
    }
  };

  const deletePhoto = (index) => {
      let removeItem = [...photoArray];
      removeItem.splice(index, 1);
      setPhotoArray(removeItem)
  };

  const store = () => {
        setStoreItems([...storeItems]);
        storeRef?.current?.close();
        Keyboard.dismiss();
  };


  return (
    <View style={styles.container}>
      {/* Header */}
      <Header         
        title={'Add Post'}
        leftComponent={
          <View style={styles.headerLeft}>
            <Image source={images.logo} style={{ height: 28, width: 28, tintColor: COLORS.primary2}} />
          </View>
        }
        rightComponent={
            <TouchableOpacity
            style={{
                width: 50,
                height: 50,
                alignItems: 'center',
                justifyContent: 'center',
            }}
            onPress= {() => console.log('Post Sumbitted') }
            >
                <Image
                source={icons.post2}
                style={{
                    width: 35,
                    height: 35,
                    tintColor: COLORS.primary2,
                }} 
                />
            </TouchableOpacity>
        }
      />
        <View style={styles.subContainer}>
          <ScrollView>
            <Text style={styles.textDetail}>Add a photo or video post with thumbnail, category, caption, price, and store details (Optional).</Text>
            
            {/* Add Thumbnail */}
            <AddPostItem label={'Thumbnail'} onPress={pickThumbnail}/>
            {thumbnail && 
              <View style={styles.thumbnail}>
                <Image source={{ uri: thumbnail }} style={styles.thumbnailPhoto} />
              </View> 
            }  

            {/* Add Media */}
            <AddPostItem label={'Media (Video/Photo)'} onPress={pickMedia} />
            <View style={{flexDirection: 'row'}}>
                {Array.from(Array(numColumns)).map((col, colIndex) => (
                      <View style={{flex: 1}} key={colIndex}>
                      {media
                      .filter((item, index) => index % numColumns === colIndex)
                      .map((item, index) => (
                        <View key={index.toString()} style={styles.mediaContainer} >                       
                            <Image source={{uri: item}} style={styles.addedMedia}/>
                            <TouchableOpacity style={styles.imageCancel} key={index} onPress={() => deleteMedia(index)}>
                                <Image source={icons.cross} style={styles.imageCancelIcon}/>
                            </TouchableOpacity>
                        </View>
                      ))}
                  </View>
                  ))
                }
            </View>

            {/* Add Details */}
            <AddPostItem label={'Details (Title, Caption, etc)'} onPress={toggleModal}/>
            {details && 
              <View style={{marginHorizontal: 20}}>
                <View style={{flexDirection: 'row', }}>
                  <Text style={{color: COLORS.primary2, ...FONTS.body4}}>Title: </Text>
                  <Text style={{color: COLORS.white, ...FONTS.body4}}>{title}</Text>
                </View> 
                <View style={{flexDirection: 'row', marginTop: 5,}}>
                  <Text style={{color: COLORS.primary2, ...FONTS.body4}}>Category: </Text>
                  <Text style={{color: COLORS.white, ...FONTS.body4}}>{category}</Text>
                </View>  
                <View style={{flexDirection: 'row', marginTop: 5,}}>
                  <Text style={{color: COLORS.primary2, ...FONTS.body4}}>Price: </Text>
                  <Text style={{color: COLORS.white, ...FONTS.body4}}>N{price}</Text>
                </View>                
                <View style={{marginTop: 5,}}>
                  <Text style={{color: COLORS.primary2, ...FONTS.body4}}>Caption: </Text>
                  <Text style={{color: COLORS.white, ...FONTS.body4}}>{caption}</Text>
                </View>
              </View>
              }
              {/* Add Store */}
              <AddPostItem label={'Store Items (Optional)'} onPress={toggleStoreModal}/>
                {storeItems.map((item, index) => {
                  return (
                    <View key={index.toString()} style={styles.itemContainer}>
                        <Text style={styles.itemName}>{item?.itemName}</Text>
                        <Text style={styles.itemPrice}>N{item?.itemPrice}</Text>
                    </View>
                  )
                })
                }
              <View>
            </View>
            </ScrollView>
        </View>
        <BottomSheetModal 
                enablePanDownToClose={true} 
                ref={detailsRef} 
                snapPoints={['100%']} 
                index={0}
                backgroundComponent={
                    ({style}) => 
                    <View style={[style, {
                        backgroundColor: COLORS.primary, 
                        borderRadius: 30, 
                    }]}/>} 
              >
                    {/* Post Details */}
                     {/* Header */}
                    <ModalHeader left={toggleModalClose} right={addDetailItem} />
                    <View style={{flex: 1, backgroundColor: COLORS.primary3, borderTopRightRadius: 35, borderTopLeftRadius: 35}}>
                      <View style={styles.addDetailText}>
                        <Text style={styles.textHeader}>Add details</Text>
                        <Text style={styles.textBody}>Provide the necessary details for your post.</Text>
                      </View>
                      <View style={{paddingHorizontal: 10}}>
                        <FormInput 
                            autoCapitalize='words'
                            placeholder={'Give it a title'}
                            onChange={setTitle}
                            value={title}
                        />
                        <FormInput 
                            autoCapitalize='words'
                            placeholder={'Category'}
                            onChange={setCategory}
                            value={category}
                        />
                        <FormMultiText
                            autoCapitalize='sentences'
                            placeholder={'Caption'}
                            onChange={setCaption}
                            multiline={true}
                            numberOfLines={4}
                            value={caption}
                        />
                        <FormInput 
                            keyboardType='number-pad'
                            placeholder={'Price (Optional)'}
                            onChange={setPrice}
                            value={price}
                        />
                      </View>
                      <Text style={{color: COLORS.gray, ...FONTS.body5, paddingHorizontal: 10, marginTop: 5, marginLeft: 65}}>Leave this input empty for a "FREE POST".</Text>                
                </View>
              </BottomSheetModal>
              <BottomSheetModal 
                  enablePanDownToClose={false} 
                  ref={storeRef} 
                  snapPoints={['100%']} 
                  index={0}
                  backgroundComponent={
                      ({style}) => 
                      <View style={[style, {
                          backgroundColor: COLORS.primary, 
                          borderRadius: 30, 
                      }]}/>} 
                >
                  <ModalHeader left={toggleStoreModalClose} right={store} />
                  <View style={styles.storeItemConatainer}>
                    <View style={{flex: 1, backgroundColor: COLORS.primary3, borderTopRightRadius: 35, borderTopLeftRadius: 35}}>
                      <View >
                        <View style={styles.titleBar}>
                            <Text style={styles.textHeader}>Add store items (Optional)</Text>
                        </View>
                        <Text style={styles.textBody}>Include items available for purchase and their item price. You can add more than one item and multiple photo(s) to each item.</Text>
                      </View>
                      {/* Store Items */}
                      <TouchableOpacity onPress={pickPhoto} style={styles.addPhotoBtn}>
                          <Text style={{color: COLORS.primary, textAlign: 'center', ...FONTS.body3}}>Add Photo(s)</Text>
                      </TouchableOpacity>
                      {/* Photo Container */}
                      <View style={{flexDirection: 'row'}}>
                        {Array.from(Array(numColumns)).map((col, colIndex) => (
                              <View style={{flex: 1}} key={colIndex}>
                              {photoArray
                              .filter((item, index) => index % numColumns === colIndex)
                              .map((item, index) => (
                                  <View key={index.toString()} style={styles.photoContainer}>                                
                                      <Image source={{uri: item}} style={styles.addedPhoto}/>
                                      <TouchableOpacity style={styles.photoCancel} onPress={() => deletePhoto(index)}>
                                          <Image source={icons.cross} style={styles.photoCancelIcon}/>
                                      </TouchableOpacity>
                                  </View>
                              ))}
                          </View>
                          ))
                        }
                      </View>
                      <View style={styles.storeInput}>
                          <TouchableOpacity onPress={addStoreItem}>
                              <View style={styles.iconContainer}>
                                  <Image  source={icons.add} style={styles.icon}/>
                              </View>
                          </TouchableOpacity>
                          <View >
                              <FormStoreInput
                                  autoCapitalize='words'
                                  placeholder={'Item Name'}
                                  onChange={setItemName}
                                  value={itemName}
                              />
                              <FormStoreInput 
                                  keyboardType='number-pad'
                                  placeholder={'Item Price'}
                                  onChange={setItemPrice}
                                  value={itemPrice}
                              />
                          </View>
                      </View>
                      <BottomSheetScrollView>
                          {storeItems.map((item, index) => {
                              return (
                                  <View key={index.toString()} style={{flexDirection: 'row', marginBottom: 10, marginTop: 5}}>
                                      <AddStoreItem  items={item}/>                                    
                                      <TouchableOpacity style={styles.cancel} key={index} onPress={() => deleteItem(index)}>
                                          <Image source={icons.cross} style={styles.cancelIcon}/>
                                      </TouchableOpacity>
                                  </View>
                                )
                            })
                          }
                      </BottomSheetScrollView>
                    </View>
                  </View>
                </BottomSheetModal>
    </View>
  )
}

export default AddPost

This post has been updated.

CodePudding user response:

You need to declare remove media outside the function delete media because everytime you call delete media. You are reinitalizing the removeMedia useState to the original media values. I did not test these codes, but from the codes I can clearly tell that you are just reinitalizing remove media back to its original value. Try this

let removeMedia=[...media];
const deleteMedia = (index) => {
  removeMedia.splice(index, 1);
  setMedia(removeMedia)
};

CodePudding user response:

I guess since we are dealing with images and not an object array that's why index wasnt working. So i changed index with items and decided to us the .filter method instead of .splice. And it worked.

const deleteMedia = (item) => {
      setMedia((prev) => prev.filter((el) => el !== item));
      console.log(item)
  };
  • Related