0

I am creating one blog with image upload. But here I am facing several issue with posting image to the backend. Whereas when I am trying to post this through POSTMAN form-data my API is working fine with able to submit my data into cloudinary via multer.

current error: Error: Multipart: Boundary not found

I have tried and looked many SO and github examples as well but I am not able to figure out my issue with current code. Any suggestion or help here please.

//My react client code.

class BlogModal extends Component {
    state = {
        blog_short_desc: '',
        blog_image_url: '',
        blog_by_author: '',
        FileName: null
    }
    onChange = (e) => {
        this.setState({ [e.target.name] : e.target.value });
    }

    onFileChange = (e) => {
        this.setState({ [e.target.name] : e.target.files[0] });
    }
    onSubmit = (e) => {
        e.preventDefault();
        const FileName = this.state.blog_image_url ; 
        const formData = new FormData();
        formData.append("File", FileName);
        const newBlog = {
            blog_short_desc: this.state.blog_short_desc,
            blog_image_url: formData,
            blog_by_author: this.props.auth["user"].name
        }
        console.log(newBlog);
        this.props.addBlog(newBlog);
        alert("Blog added successfully!");
    }
    render(){
       
        return(
            <div>
                <Form onSubmit ={this.onSubmit } enctype="multipart/form-data">
                    <FormGroup>
                        <Label for="blogHeading">Blog Heading</Label>
                        <Input type="text" name="blog_short_desc" id="blogHeading" placeholder="Add one liner"
                        onChange={this.onChange} required/>

                        <Label for="blogImageURl">Image Url</Label>
                        <Input type="file" name="blog_image_url" id="blogImageURl" placeholder="Add image url "
                        onChange={this.onFileChange} />
                        
                        <Button color="dark" style={{marginTop: '2rem'}} block>Add blog</Button>
                    </FormGroup>
                </Form>
            </div>
        )
    }
}

const mapStateToProps = state => ({
    resume: state.resume,
    auth: state.auth
})

export default connect(mapStateToProps, { addBlog })(BlogModal);

//add action

export const addBlog = blog => (dispatch, getState) => {
    
   axios
   .post('/api/blogs', blog, tokenConfig(getState))
   .then(res => 
    dispatch({
        type: types.ADD_BLOG,
        payload: res.data
    })).catch (err => dispatch (returnErrors(err.response.data, err.response.status)));
    debugger
};

//token config

export const tokenFormConfig = getState => {
    //Get token from local storage
    const token = getState().auth.token;
    // headers
    const config = {
        headers: {
            Accept: 'application/json',
            'Content-Type': 'multipart/form-data',
        }
    }
    //if token then add to headers
    if(token) {
        config.headers['x-auth-token'] = token;
    }
return config;
};

//blog router

router.post('/', upload.single('blog_image_url'), async (req, res, next) => {

    try {
    const result = await cloudinary.uploader.upload(req.file.path);
    const newBlog = new Blog({
        blog_short_desc: req.body.blog_short_desc,
        blog_image_url: result.secure_url,
        blog_by_author: req.body.blog_by_author

    });

    await newBlog.save().then(blogs => res.json(blogs));
    next();
    } catch (error) {
        next(error);
    }
});

//blog model

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const BlogSchema = new Schema({
    blog_short_desc: {
        type: String,
        required: true
    },
    blog_image_url: {
        type: String,
        required: true
    },
    blog_by_author:{
        type: String,
        required: true
    },
    date: {
        type: Date,
        default: Date.now
    }
});

module.exports = Blog = mongoose.model('blog', BlogSchema);

//current error

`Error: Multipart: Boundary not found`

enter image description here

//current UI

enter image description here

//when submitting via POSTMAN form-data

enter image description here

Tammy
  • 1,122
  • 5
  • 19
  • 50

1 Answers1

1

FormData.append() contains all the data you want to send, and should have the file added to it, not just the name.

Hope this helps:

// BlogModal

onSubmit = (e) => {
    e.preventDefault();
    const newBlog = new FormData();
    newBlog.append("blog_short_desc", this.state.blog_short_desc);
    newBlog.append("blog_image_url", this.state.blog_image_url);
    newBlog.append("blog_by_author", this.state.blog_by_author);
    console.log(newBlog);
    this.props.addBlog(newBlog);
    alert("Blog added successfully!");
}

// Add action

export const addBlog = blog => (dispatch, getState) => {
    axios({
        url: '/api/blogs',
        method: 'post',
        data: bodyFormData,
        headers: {
            'Content-Type': 'multipart/form-data',
        }
    })
    .then(res => 
        dispatch({
            type: types.ADD_BLOG,
            payload: res.data
        }))
    .catch (err => dispatch (returnErrors(err.response.data, err.response.status)));
    debugger
};
Emre Koc
  • 1,481
  • 10
  • 18
  • Hi Emre, Thank youf for your time. but I am getting error here as well . I have updated my code. – Tammy Jul 22 '20 at 13:41
  • Edited the answer to include bits of your code, hope that helps – Emre Koc Jul 22 '20 at 14:09
  • 1
    Also check out this answer: https://stackoverflow.com/questions/47630163/axios-post-request-to-send-form-data – Emre Koc Jul 22 '20 at 14:10
  • Thank you Emre. You just genious. I was looking for this solutions only afterhitting my head for 20 hrs . finally you have solved my issue. Thank you. – Tammy Jul 22 '20 at 14:25