TransWikia.com

"Multipart/form-data" is not woking in React-redux form upload

Stack Overflow Asked on November 10, 2021

I am facing some problem in getting the file upload value from input type file.
what I am getting is the file path name but I want to get the whole path for uploading it into cloudinary.
When I am sending data from postman form-data it is working fine but through frontend I am not getting that unexpected result.

any suggestion what I can change here ?

//Blog.js

class BlogModal extends Component {
    state = {
        modal: false,
        blog_short_desc: '',
        blog_image_url: '',
        blog_by_author: ''
    }

    static propTypes = {
        auth: PropTypes.object.isRequired
    }

    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 newBlog = {
            blog_short_desc: this.state.blog_short_desc,
            blog_image_url: FileName,
            blog_by_author: this.props.auth["user"].name
        }
        console.log(newBlog);
        //Add item via addItem action
        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);

//action

export const addBlog = blog => (dispatch, getState) => {
    
    const config = {
        headers: {
            Accept: 'application/json',
            'Content-Type': 'multipart/form-data',
        }
    }
   axios
   .post('/api/blogs', blog, tokenConfig(getState), config)
   .then(res => 
    dispatch({
        type: types.ADD_BLOG,
        payload: res.data
    })).catch (err => dispatch (returnErrors(err.response.data, err.response.status)));
    
};

//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_name: req.body.blog_name,
        blog_desc: req.body.blog_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);
    }
});

//tokenconfig

// setup config/headers and token
export const tokenConfig = getState => {
        //Get token from local storage
        const token = getState().auth.token;

        // headers
        const config = {
            headers: {
                "content-type": "application/json"
            }
        }
    
        //if token then add to headers
    
        if(token) {
            config.headers['x-auth-token'] = token;
        }
    return config;
};

//current value in network panel

blog_by_author: "Tanmoy Sarkar"
blog_desc: "fddgdfgfd"
blog_image_url: {}
blog_name: "sirirrrheyyy siri"
blog_short_desc: "How I learned the Ups & downs"

//Expected value ( now via postman set through form data)

{ asset_id: '9f271dc05712daf92b05702d95549c5a',
[0]   public_id: 'bia1qqug7bkrz1n29wai',
[0]   version: 1595352697,
[0]   version_id: '632b918f3b664cee4661e7c124786e8c',
[0]   signature: '981e2cc7c5e90a7cf8adf517cb79513132737f60',
[0]   width: 675,
[0]   height: 505,
[0]   format: 'jpg',
[0]   resource_type: 'image',
[0]   created_at: '2020-07-21T17:31:37Z',
[0]   tags: [],
[0]   bytes: 211385,
[0]   type: 'upload',
[0]   etag: '269901e75a4d992a40c2507e884b5a2b',
[0]   placeholder: false,
[0]   url:
[0]    'http://res.cloudinary.com/tammycloudinary/image/upload/v1595352697/bia1qqug7bkrz1n29wai.jpg',
[0]   secure_url:
[0]    'https://res.cloudinary.com/tammycloudinary/image/upload/v1595352697/bia1qqug7bkrz1n29wai.jpg',
[0]   original_filename: 'tmp-1-1595352688726' }

//from network panel
enter image description here

//content type is still application/json with empty file object

enter image description here

//Working with postman form-data

enter image description here

One Answer

So, I'm guessing you're using multer, if I'm right, you gotta use req.file instead of req.files.blog_image_url since you defined it as a single file, in multer docs there is an example:

app.post('/profile', upload.single('avatar'), function (req, res, next) {
  // req.file is the `avatar` file
  // req.body will hold the text fields, if there were any
})

also, you want to make sure that request has a Content-Type header with the value of "multipart/form-data".

axios accepts config object as the third parameter, and there's no support fourth parameter. probably you're returning an object in tokenConfig(getState) which contains a header object, so you gotta merge that with:

headers: {
    Accept: 'application/json',
    'Content-Type': 'multipart/form-data',
}

Answered by StackedQ on November 10, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP