1

I used componentDidUpdate and in it I put a shift method, which is used to delete an object from a JSON array and thereby re-render the displayed posts, but the shift method deletes the first object from the array independently in which the delete button on the post will I press? Is there any possibility, then, to bypass the deletion of the first element in favor of the one that is designated to be deleted?

componentDidUpdate(prevProps, prevState) {
        const {posts} = this.props;
        const indexPosts = posts.findIndex((post) => post.id === this.state.postId);

        if(prevProps.posts !== posts){
            this.handleData();
        } else if (indexPosts !== -1)
        {
            this.informationAlert();
            const log = posts.splice(indexPosts, 1);
            console.log(log);
        }   
    }

EDIT: Actions

export const deletedPost = (id) => (dispatch) => {
    axios
        .delete(`https://jsonplaceholder.typicode.com/posts/${id}`, id, {
            headers: {
                'Content-type': 'application/json'
            }
        })
        .then((post) =>
            dispatch({
                type: DELETED_POST,
                payload: post.data
            })
        )
        .catch((err) => console.log(err));
};
import { FETCH_POSTS, NEW_POST, DELETED_POST, FETCH_COMMENTS, NEW_COMMENT } from '../actions/types';

const initialState = {
    items: [],
    item: {},
    itemComent: [],
    itemNewComment: {},
    deletedPost: []
};

export default function (state = initialState, action) {
    switch (action.type) {
        case FETCH_POSTS:
            return {
                ...state,
                items: action.payload
            };
        case NEW_POST:
            return {
                ...state,
                item: action.payload
            };
        case DELETED_POST:
            return {
                ...state,
                deletedPost: action.payload
            };
        case FETCH_COMMENTS:
            return {
                ...state,
                itemComent: action.payload
            }
        case NEW_COMMENT:
            return {
                ...state,
                itemNewComment: action.payload
            }
        default:
            return state;
    }
}

EDIT 2:

const mapStateToProps = (state) => ({
    posts: state.posts.items,
    newPost: state.posts.item,
    deletedPost2: state.posts.deletedPost
});

EDIT 3:

handleDeletedPost = (id) => {
        this.setState({
            postId: id
        })
    }

Edit 4:

//I added in constructor 
this.state: dataPost: '',

//next I create function to load data and send to state dataPost
handleData = (e) => {
        const {posts} = this.props;
        const {dataPost} = this.state;
        const letang = posts;
        const postsData = dataPost;

        if (postsData.length <= 0) {            
            this.setState({
                dataPost: letang
            })
        } else {
            console.log('stop')
        }       
    }
// next i create in componentDidUpdate this code
componentDidUpdate(prevProps, prevState) {
        const {posts} = this.props;
        const indexPosts = posts.findIndex((post) => post.id === this.state.postId);

        if(prevProps.posts !== posts){
            this.handleData();
        } else if (indexPosts !== -1)
        {
            this.informationAlert();
            const log = posts.splice(indexPosts, 1);
            console.log(log);
        }   
    }

** When I added loop if (indexPosts !== -1) then my array is cut only one object :-) API Posts: https://jsonplaceholder.typicode.com/posts/

The results are visible at this link when you press details and then the delete icon: https://scherlock90.github.io/api-post-task/

4
  • 2
    you should also not be mutating props like that. Create a piece of state that holds your mutated array. Commented Jun 5, 2019 at 15:58
  • Please post your sample array and what is in deletedPost. Commented Jun 5, 2019 at 16:04
  • @Chase why is this the wrong way to mutate data? Commented Jun 5, 2019 at 16:21
  • I added the first post probably the information you asked for. @kiranvj Commented Jun 5, 2019 at 16:24

4 Answers 4

2

You need to use splice to delete an element from array. In splice you need to provide startIndex and number of elements to remove in second argument. In below code find index using `findIndex method, second argument is 1 as we need to remove only 1 element.

Try this

componentDidUpdate (prevProps, prevState) {
        if (prevProps.deletedPost) {
            const { posts } = this.props
            const letang = posts.splice(posts.findIndex( (post)=> post.id === prevProps.deletedPost.id), 1);

           console.log(posts); // this should have array without deletedPost
        }
    }
Sign up to request clarification or add additional context in comments.

6 Comments

Answers which explain the code they introduce are more useful than those which do not...
@kiranvj Your proposal results in an empty table, but no post is removed
@Sen console.log(posts); // this should have array without deletedPost
Yes I have, and there is empty array
But i change to const letang = this.props.posts.slice(this.props.posts.findIndex( (post)=> post.id === this.state.postId), 1); then i see first posts in console log
|
1

This might help:

componentDidUpdate (prevProps, prevState) {
    if (prevProps.deletedPost) {
        const letang = this.props.posts;
        letang.splice(deletedPost, 1);
    }
}

the slice() takes the index of the object and an optional number of items to delete. since you just want to delete a single object you pass 1.

2 Comments

I tried a methody splice, but it still erases the first element from the array and not the selected one
is the deletePost an object or an id?
1

This might help, try filtering out the object you dont want in the array.

componentDidUpdate (prevProps, prevState) {
    if (prevProps.deletedPost) {
        const letang = this.props.items.filter(p => p.id !== prevProps.deletedPost.id);
    }
}

UPDATED I think you should be deleting the items in your redux store rather than trying to delete the posts from your api since the api might rather be generating the same data randomly. Change your actionCreator to

export const deletedPost = (id) => {
   dispatch({
       type: DELETED_POST, 
       payload: id 
   });
};

Then use this in your reducer so you can focus on items array coming from your reducer store. Then remove deletedPost: [] from your reducer.

...
    case DELETED_POST:
        const newItems = state.items.filter(p => p.id !== action.payload);
        return {
            ...state,
            items: [ ...newItems ],
        };
...

6 Comments

@SeN from your reducer, you are using items instead of posts, try replacing this.props.posts.filter with this.props.items.filter
but if you see EDIT 2 then you see why is posts
@SeN okay. now i see you are using deletedPost2 in your mapStateToProps. change the prevProps.deletedPost.id to prevProps.deletedPost2.id
then i see error : "Uncaught TypeError: Cannot read property 'filter' of undefined at Posts.componentDidUpdate "
in console log I see a change in the sense of one post less always selected, but unfortunately it does not render the state in the displayed objects in the app. And it is always one element that disappears, not that the selected posts are subtracted one by one
|
0

use splice() to delete :), you can find the index of post which should be deleted and then delete it by using this method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.