A
A
alexmc812019-03-05 18:56:00
React
alexmc81, 2019-03-05 18:56:00

I don't understand why it's not possible to apply optimistic ui when adding a comment?

Hello, the problem is that when I try to immediately add the created comment to the list of comments from the database using the update parameter of the Mutation component, I get the following errors:
Missing field _id in {
"video": "5c7e28fa34238b298846c82e",
"user": "alex",
"comment": "Comment",
"__
Missing field createdDate in {
"video": "5c7e28fa34238b298846c82e",
"user": "alex",
"comment": "Comment",
"__
Here is the relevant code
graphql comment schema

type VideoComment {
        _id: ID
        comment: String!
        createdDate: String
        video: String!
        user: String!
    }

Query in schema Query in react-apollo
getVideoComments(video: String!): [VideoComment]
export const ADD_VIDEO_COMMENT = gql`
  mutation($video: String!, $user: String!, $comment: String!) {
    addVideoComment(video: $video, user: $user, comment: $comment) {
      video
      user
      comment
    }
  }
`;

react component sending request
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
import { Mutation } from 'react-apollo';
import { ADD_VIDEO_COMMENT, GET_VIDEO_COMMENTS } from '../../../queries';

import Error from '../Error/Error';
import withSession from '../../../hoc/withSession';

const initialState = {
  user: '',
  comment: '',
};

class AddComment extends Component {
  state = {
    ...initialState,
  };

  clearState = () => {
    this.setState({ ...initialState });
  };

  validateForm = () => {
    const { comment } = this.state;
    const isInvalid = !comment;
    return isInvalid;
  };

  changeHandler = event => {
    const { name, value } = event.target;
    this.setState({
      [name]: value,
    });
  };

  submitHandler = (event, addVideoComment) => {
    event.preventDefault();
    addVideoComment()
      .then(({ data }) => {
        console.log(data);
        this.clearState();
      })
      .catch(err => {
        console.log(err.message);
      });
  };

  updateCache = (cache, { data: { addVideoComment } }) => {
    console.log(addVideoComment);
    const { video } = this.props;
    const { getVideoComments } = cache.readQuery({
      query: GET_VIDEO_COMMENTS,
      variables: { video },
    });
    cache.writeQuery({
      query: GET_VIDEO_COMMENTS,
      variables: { video },
      data: {
        getVideoComments: [addVideoComment, ...getVideoComments],
      },
    });
  };

  componentDidMount() {
    if (this.props.session.getCurrentUser) {
      const { userName } = this.props.session.getCurrentUser;
      this.setState({
        user: userName,
      });
    }
  }

  render() {
    const { user, comment } = this.state;
    const { video } = this.props;
    return (
      <Mutation
        mutation={ADD_VIDEO_COMMENT}
        variables={{ video, user, comment }}
        update={this.updateCache}>
        {(addVideoComment, { data, loading, error }) => {
          return (
            <div>
              {error && <Error error={error} />}
              <form
                onSubmit={event => this.submitHandler(event, addVideoComment)}>
                <textarea
                  name='comment'
                  placeholder='Ваш комментарий'
                  cols='30'
                  rows='10'
                  value={comment}
                  onChange={this.changeHandler}
                />
                <button type='submit' disabled={loading || this.validateForm()}>
                  Добавить комментарий
                </button>
              </form>
            </div>
          );
        }}
      </Mutation>
    );
  }
}

In principle, it is clear from the errors that when creating a comment, the newly created object in the cache lacks the _id and createdDate parameters. But how can they be passed to the cache if they are already created in the database after adding the comment?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
alexmc81, 2019-03-06
@alexmc81

Thanks for the answer, but now when passing to mutation addVideoComment _id: -1 I get the following error when adding a comment - GraphQL error: VideoComment validation failed: _id: Cast to ObjectID failed for value "-1" at path "_id"

updateCache = (cache, { data: { addVideoComment } }) => {
    console.log(addVideoComment);
    const { video } = this.props;
    const { getVideoComments } = cache.readQuery({
      query: GET_VIDEO_COMMENTS,
      variables: { video },
    });
    cache.writeQuery({
      query: GET_VIDEO_COMMENTS,
      variables: { video },
      data: {
        getVideoComments: [addVideoComment, ...getVideoComments],
      },
    });
  };

  render() {
    const { user, comment } = this.state;
    const { video } = this.props;
    return (
      <Mutation
        mutation={ADD_VIDEO_COMMENT}
       variables={{ _id: -1, video, user, comment, createdDate: new Date() }}
        update={this.updateCache}>
        {(addVideoComment, { data, loading, error }) => {
          return (
            <div>
              {error && <Error error={error} />}
              <form
                onSubmit={event => this.submitHandler(event, addVideoComment)}>
                <textarea
                  name='comment'
                  placeholder='Ваш комментарий'
                  cols='30'
                  rows='10'
                  value={comment}
                  onChange={this.changeHandler}
                />
                <button type='submit' disabled={loading || this.validateForm()}>
                  Добавить комментарий
                </button>
              </form>
            </div>
          );
        }}
      </Mutation>
    );
  }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question