я получаю это сообщение каждый раз, когда пытаюсь обновить профиль в своем веб-приложении - PullRequest
2 голосов
/ 20 марта 2020

Я пытаюсь создать веб-приложение с реакцией, редуксом и узлом, где я могу создавать и редактировать данные профиля. У меня есть одна функция, управляющая обеими ситуациями, поэтому при создании она работает нормально, но при редактировании выдает сообщение об ошибке, проверил мой код много раз, но я не вижу проблемы

это сообщение об ошибке

  Proxy error: Could not proxy request /api/profile from localhost:3000 to http://localhost:5000/.
[1] See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
[1]
[1] Proxy error: Could not proxy request /api/profile from localhost:3000 to http://localhost:5000/.
[1] See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).
[1]
[0] server started in port 5000
[0] MongoDB connected
[1] Compiled with warnings.
[1]
[1] ./src/components/profile-form/EditProfile.js
[1]   Line 48:6:  React Hook useEffect has missing dependencies: 'getCurrentProfile', 'profile.bio', 'profile.company', 'profile.githubusername', 'profile.location', 'profile.skills', 'profile.social', 'profile.status', and 'profile.website'. Either include them or remove the dependency array. If 'getCurrentProfile' changes too often, find the parent component that defines it and wrap that definition in useCallback  react-hooks/exhaustive-deps

это второе сообщение об ошибке, которое я получил

(node:10664) UnhandledPromiseRejectionWarning: TypeError: skills.split is not a function
[0]     at D:\Algorarhim and data structure\social app new version\router\api\profile.js:77:36
[0]     at Layer.handle [as handle_request] (D:\Algorarhim and data structure\social app new version\node_modules\express\lib\router\layer.js:95:5)
[0]     at next (D:\Algorarhim and data structure\social app new version\node_modules\express\lib\router\route.js:137:13)
[0]     at middleware (D:\Algorarhim and data structure\social app new version\node_modules\express-validator\src\middlewares\check.js:15:13)
[0]     at processTicksAndRejections (internal/process/task_queues.js:97:5)
[0] (node:10664) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
[0] (node:10664) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

это функция, управляющая редактированием и созданием

import axios from 'axios';
import { setAlerts } from './alert';
import { GET_PROFILE, PROFILE_ERROR } from './types';

// Create or Update profile

export const createProfile = (
  formData,
  history,
  edit = false
) => async dispatch => {
  try {
    const config = {
      headers: {
        'Content-Type': 'application/json'
      }
    };

    const res = await axios.post('/api/profile', formData, config);

    dispatch({
      type: GET_PROFILE,
      payload: res.data
    });

    dispatch(
      setAlerts(edit ? 'Profile Updated' : 'Profile Created', 'success')
    );

    if (!edit) {
      history.push('/dashboard');
    }
  } catch (err) {
    const errors = err.response.data.error;

    if (errors) {
      errors.forEach(error => dispatch(setAlerts(error.msg, 'danger')));
    }

    dispatch({
      type: PROFILE_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status }
    });
  }
};

это компонент, который я пытаюсь использовать в этой функции

import React, { useState, Fragment, useEffect } from 'react';
import { withRouter, Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createProfile, getCurrentProfile } from '../../actions/profile';
const EditProfile = ({
  profile: { profile, loading },
  createProfile,
  getCurrentProfile,
  history
}) => {
  const [formDate, setFormDate] = useState({
    company: '',
    website: '',
    location: '',
    status: '',
    skills: '',
    githubusername: '',
    bio: '',
    twitter: '',
    facebook: '',
    linkedin: '',
    youtube: '',
    instagram: ''
  });

  const [displaySocialInput, toggleSocialInput] = useState(false);

  useEffect(() => {
    getCurrentProfile();

    setFormDate({
      company: loading || !profile.company ? '' : profile.company,
      website: loading || !profile.website ? '' : profile.website,
      location: loading || !profile.location ? '' : profile.location,
      status: loading || !profile.status ? '' : profile.status,
      skills: loading || !profile.skills ? '' : profile.skills,
      githubusername:
        loading || !profile.githubusername ? '' : profile.githubusername,
      bio: loading || !profile.bio ? '' : profile.bio,
      twitter: loading || !profile.social ? '' : profile.social.twitter,
      facebook: loading || !profile.social ? '' : profile.social.facebook,
      linkedin: loading || !profile.social ? '' : profile.social.linkedin,
      youtube: loading || !profile.social ? '' : profile.social.youtube,
      instagram: loading || !profile.social ? '' : profile.social.instagram
    });
    // console.log(profile.company);
  }, [loading]);
  const {
    company,
    website,
    location,
    status,
    skills,
    githubusername,
    bio,
    twitter,
    facebook,
    linkedin,
    youtube,
    instagram
  } = formDate;

  const onChange = e =>
    setFormDate({ ...formDate, [e.target.name]: e.target.value });

  const onSubmit = e => {
    e.preventDefault();
    createProfile(formDate, history, true);
  };

  return (
    <Fragment>
      <h1 className='large text-primary'>Create Your Profile</h1>
      <p className='lead'>
        <i className='fas fa-user'></i> Let's get some information to make your
        profile stand out
      </p>
      <small>* = required field</small>
      <form className='form' onSubmit={e => onSubmit(e)}>
        <div className='form-group'>
          <select name='status' value={status} onChange={e => onChange(e)}>
            <option value='0'>* Select Professional Status</option>
            <option value='Developer'>Developer</option>
            <option value='Junior Developer'>Junior Developer</option>
            <option value='Senior Developer'>Senior Developer</option>
            <option value='Manager'>Manager</option>
            <option value='Student or Learning'>Student or Learning</option>
            <option value='Instructor'>Instructor or Teacher</option>
            <option value='Intern'>Intern</option>
            <option value='Other'>Other</option>
          </select>
          <small className='form-text'>
            Give us an idea of where you are at in your career
          </small>
        </div>
        <div className='form-group'>
          <input
            type='text'
            placeholder='Company'
            name='company'
            value={company}
            onChange={e => onChange(e)}
          />
          <small className='form-text'>
            Could be your own company or one you work for
          </small>
        </div>
        <div className='form-group'>
          <input
            type='text'
            placeholder='Website'
            name='website'
            value={website}
            onChange={e => onChange(e)}
          />
          <small className='form-text'>
            Could be your own or a company website
          </small>
        </div>
        <div className='form-group'>
          <input
            type='text'
            placeholder='Location'
            name='location'
            value={location}
            onChange={e => onChange(e)}
          />
          <small className='form-text'>
            City & state suggested (eg. Boston, MA)
          </small>
        </div>
        <div className='form-group'>
          <input
            type='text'
            placeholder='* Skills'
            name='skills'
            value={skills}
            onChange={e => onChange(e)}
          />
          <small className='form-text'>
            Please use comma separated values (eg. HTML,CSS,JavaScript,PHP)
          </small>
        </div>
        <div className='form-group'>
          <input
            type='text'
            placeholder='Github Username'
            name='githubusername'
            value={githubusername}
            onChange={e => onChange(e)}
          />
          <small className='form-text'>
            If you want your latest repos and a Github link, include your
            username
          </small>
        </div>
        <div className='form-group'>
          <textarea
            placeholder='A short bio of yourself'
            name='bio'
            value={bio}
            onChange={e => onChange(e)}
          />
          <small className='form-text'>Tell us a little about yourself</small>
        </div>

        <div className='my-2'>
          <button
            onClick={() => toggleSocialInput(!displaySocialInput)}
            type='button'
            className='btn btn-light'
          >
            Add Social Network Links
          </button>
          <span>Optional</span>
        </div>
        {displaySocialInput && (
          <Fragment>
            <div className='form-group social-input'>
              <i className='fab fa-twitter fa-2x'></i>
              <input
                type='text'
                placeholder='Twitter URL'
                name='twitter'
                value={twitter}
                onChange={e => onChange(e)}
              />
            </div>

            <div className='form-group social-input'>
              <i className='fab fa-facebook fa-2x'></i>
              <input
                type='text'
                placeholder='Facebook URL'
                name='facebook'
                value={facebook}
                onChange={e => onChange(e)}
              />
            </div>

            <div className='form-group social-input'>
              <i className='fab fa-youtube fa-2x'></i>
              <input
                type='text'
                placeholder='YouTube URL'
                name='youtube'
                value={youtube}
                onChange={e => onChange(e)}
              />
            </div>

            <div className='form-group social-input'>
              <i className='fab fa-linkedin fa-2x'></i>
              <input
                type='text'
                placeholder='Linkedin URL'
                name='linkedin'
                value={linkedin}
                onChange={e => onChange(e)}
              />
            </div>

            <div className='form-group social-input'>
              <i className='fab fa-instagram fa-2x'></i>
              <input
                type='text'
                placeholder='Instagram URL'
                name='instagram'
                value={instagram}
                onChange={e => onChange(e)}
              />
            </div>
          </Fragment>
        )}

        <input type='submit' className='btn btn-primary my-1' />
        <Link className='btn btn-light my-1' to='/dashboard'>
          Go Back
        </Link>
      </form>
    </Fragment>
  );
};

EditProfile.propTypes = {
  createProfile: PropTypes.func.isRequired,
  getCurrentProfile: PropTypes.func.isRequired,
  profile: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  profile: state.profile
});

export default connect(mapStateToProps, { createProfile, getCurrentProfile })(
  withRouter(EditProfile)
);

это мой маршрутизатор api для создания и редактирования профиля

// @route   post api/profile
// @ desc   Create or update Current user profile
// @access  private

router.post(
  '/',
  [
    auth,
    [
      check('status', 'Status is required')
        .not()
        .isEmpty(),
      check('skills', 'Skills is required')
        .not()
        .isEmpty()
    ]
  ],
  async (req, res) => {
    const error = validationResult(req);
    if (!error.isEmpty()) {
      return res.status(400).json({ error: error.array() });
    }

    const {
      company,
      website,
      location,
      bio,
      status,
      githubusername,
      skills,
      youtube,
      facebook,
      twitter,
      instagram,
      linkedin
    } = req.body;

    // Build profile object
    const profileField = {};
    profileField.user = req.user.id;
    if (company) profileField.company = company;
    if (website) profileField.website = website;
    if (location) profileField.location = location;
    if (bio) profileField.bio = bio;
    if (status) profileField.status = status;
    if (githubusername) profileField.githubusername = githubusername;
    if (skills) {
      profileField.skills = skills.split(',').map(skills => skills.trim());
    }

    //Build social object
    profileField.social = {};
    if (youtube) profileField.social.youtube = youtube;
    if (twitter) profileField.social.twitter = twitter;
    if (facebook) profileField.social.facebook = facebook;
    if (linkedin) profileField.social.linkedin = linkedin;
    if (instagram) profileField.social.youtube = instagram;

    try {
      let profile = await Profile.findOne({ user: req.user.id });

      if (profile) {
        //update
        profile = await Profile.findOneAndUpdate(
          { user: req.user.id },
          { $set: profileField },
          { new: true }
        );

        return res.json(profile);
      }

      // Create
      profile = new Profile(profileField);

      await profile.save();
      res.json(profile);
    } catch (e) {
      console.error(err.message);
      res.status(500).send('Server error');
    }
  }
);

Ответы [ 2 ]

1 голос
/ 21 марта 2020

Вы должны вставить навыки как строку, потому что функция split работает так, что она разбивает строку на массив разделенных строк.

a = "something, somethingelse, whatever" // that is correct
b = ["something", "somethingelse", "whatever"] // that gives error
c = []
const profileField = {};
console.log(profileField);

// Good result
profileField.skills = a.split(",").map(skills => skills.trim())

console.log(profileField.skills)
// result => [ 'something', 'somethingelse', 'whatever' ]



// TypeError result, comment to see good result
profileField.skills = b.split(",").map(skills => skills.trim())

console.log(profileField.skills)
// result => TypeError: b.split is not a function


// Bad result, Arrays cannot work with split function
// profileField.skills = c.split(",").map(skills => skills.trim())

// console.log(profileField.skills)

// to run node filename.js
0 голосов
/ 20 марта 2020

Из того, что я вижу, навыки - это просто строка, поэтому вы не можете сделать карту на строковую переменную (вы можете сделать карту на массивах). Попробуйте это:

if (skills) {
      profileField.skills = skills.split(',').trim();
    }

Если это не сработает, перед этой строкой вставьте:

console.log(skills)

и проверьте, какие данные вы получите, и покажите их здесь. Если этот первый вариант не работает, и вы отправляете мне результат console.log, я постараюсь ответить на этот вопрос завтра (около 8-9 часов).

...