1

I've made a flutter application which will open the camera and capture an image . What I want to do is to send that image to the backend using the http post services. I've created an api using node js and the problem im facing is that I dont know how to send the image to the backend ....please help

heres my code , can you please check whats wrong because the node.js part works fine when tested with postman. Im assuming its something to do with the front end.

Flutter front end code

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';

class LandingScreen extends StatefulWidget {
  @override
  _LandingScreenState createState() => _LandingScreenState();
}

class _LandingScreenState extends State<LandingScreen> {
  PickedFile imageFile;
  Dio dio = new Dio();

  _openCamera(BuildContext context) async {
  //holds the image taken by the camera
var picture = await ImagePicker().getImage(source: ImageSource.camera);
if (picture != null) {
  this.setState(() {
    imageFile = picture;
  });
}
try {
  //Extracting the file name from the file
  String filename = imageFile.path.split('/').last;
  FormData formData = new FormData.fromMap({
    "image": await MultipartFile.fromFile(imageFile.path,
        filename: filename, contentType: new MediaType('image', 'png')),
    "type": "image/png"
  });
  //sending to the server
  Response response = await dio.post("http://localhost:3000/tea/",
      data: formData,
      options: Options(headers: {
        "accept": "*/*",
        "Authorization": "Bearer accesstoken",
        "Content-Type": "multipart/form-data"
      }));
} catch (e) {
  print(e);
}
}

 Widget _decideImageView() {
if (imageFile == null) {
  return Text("No selected Image");
} else {
  return Image.file(File(imageFile.path), width: 500, height: 400);
}
}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
    body: Container(
    color: Colors.indigo[900],
    child: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          _decideImageView(),
          SizedBox(
            height: 300,
            width: 420,
            child: RaisedButton.icon(
              onPressed: () {
                _openCamera(context);
                // _showChoiceDialog(context);
              },
              label: Text(
                'OPEN CAMERA',
                style: TextStyle(color: Colors.white, fontSize: 20),
              ),
              icon: Icon(
                Icons.camera_alt_outlined,
                color: Colors.white,
                size: 200,
              ),
              color: Colors.deepOrange,
            ),
          ),
        ],
      ),
    ),
  ),
);
}
}

server.js file

//import mongoose
const mongoose = require('mongoose');


   //establish connection to database
   const MongoClient = require('mongodb').MongoClient;
   const uri = "mongodb+srv://xxxxxxx:<password>@cluster0.s42z9.mongodb.net/myFirstDatabase? 
   retryWrites=true&w=majority";
   const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
   client.connect(err => {
   const collection = client.db("test").collection("devices");
   // perform actions on the collection object
   client.close();
   });

     const express = require("express");
     const routes = require('./routes/image'); // import the routes

     const app = express();

     app.use(express.json()); // parses incoming requests with JSON payloads

     app.use('/', routes); //to use the routes

     app.use('/uploads', express.static('./uploads'));

     const listener = app.listen(process.env.PORT || 3000, () => {
     console.log('App is listening on port ' + listener.address().port)
      })

image.js(models)

const mongoose = require("mongoose"); //import mongoose

  // tea schema
  const TeaSchema = new mongoose.Schema({
    name: {type:String, required:true},
    image: String
    //description: String,
    //keywords: String,
    //origin: String,
    //brew_time: Number,
   //temperature: Number,
   //comments: [{ text: String, date: {type:String, default: new Date()} }]
    });

   const Tea = mongoose.model('Tea', TeaSchema); //convert to model named Tea
   module.exports = Tea; //export for controller use

image.js(routes)

const express = require('express'); //import express

// 1.
const router  = express.Router(); 
// 2.
const teaController = require('../controllers/image'); 
// 3.
//router.post('/image', imageController.newImage); 
//router.post('/image2',imageController.newImage2);
router.post('/tea', teaController.uploadImg /*insert this guy*/ , teaController.newTea);
router.get('/tea', teaController.getAllTea);
router.delete('/tea', teaController.deleteAllTea);

router.get('/tea/:name', teaController.getOneTea);
router.post('/tea/:name', teaController.newComment);
router.delete('/tea/:name', teaController.deleteOneTea);

// 4. 
module.exports = router; // export to use in server.js

image.js(controllers)

const multer = require('multer');

const storage = multer.diskStorage({
destination: function (req, file, cb) {
    cb(null, './uploads');
  },
filename: function (req, file, cb) {
    cb(null, file.originalname);
}
});
  const uploadImg = multer({storage: storage}).single('image');

 //import tea model
 const Tea = require('../models/image');
 // newTea function for post image route
 const newImage = (req, res, next) => {
  res.json({message: "POST new image"}); // dummy function for now
   };
   const newImage2 = (req, res, next) => {
      res.json({message: "POST new image2"}); // dummy function for now
    };

   //GET '/tea'
   const getAllTea = (req, res, next) => {
     //check if the tea name already exists in db
     //Tea.findOne({name:req.body.name},(data)=>{

    //if tea not in db, add it
    //if(data===null){
        //create a new tea object using the Tea model and req.body
        const newTea = new Tea({
            name:req.body.name,
            image: req.body.image, // placeholder for now
            description: req.body.description,
            keywords: req.body.keywords,
            origin: req.body.origin,
            brew_time: req.body.brew_time,
            temperature: req.body.temperature,
        })

        // save this object to database
        //newTea.save((err, data)=>{
        //    if(err) return res.json({Error: err});
        //    return res.json(data);
        //})
    //if tea is in db, return a message to inform it exists            
    //}else{
        return res.json(newTea);
      //}
    //})    
      };

    //POST '/tea'
    const newTea = (req, res, next) => {
     //check if the tea name already exists in db
     Tea.findOne({name:req.body.name},(data)=>{

       //if tea not in db, add it
       if(data===null){
            console.log("new object is creating");
           //create a new tea object using the Tea model and req.body
               const newTea = new Tea({
               name:req.body.name,
               image: req.file.path // placeholder for now
               //description: req.body.description,
               //keywords: req.body.keywords,
              //origin: req.body.origin,
              //brew_time: req.body.brew_time,
              //temperature: req.body.temperature,
           })

           // save this object to database
           newTea.save((err, data)=>{
               if(err) return res.json({Error: err});
               console.log("saved");
               return res.json(data);
           
             })
         //if tea is in db, return a message to inform it exists            
          }else{
            console.log("not saved");
             return res.json(newTea);
        
             }
            }) 
             }

         //DELETE '/tea'
         const deleteAllTea = (req, res, next) => {
         res.json({message: "DELETE all tea"});
         };

          //GET '/tea/:name'
          const getOneTea = (req, res, next) => {
          res.json({message: "GET 1 tea"});
            };

           //POST '/tea/:name'
           const newComment = (req, res, next) => {
           res.json({message: "POST 1 tea comment"});
           };

          //DELETE '/tea/:name'
          const deleteOneTea = (req, res, next) => {
            res.json({message: "DELETE 1 tea"});
           };


             module.exports = {newImage,newImage2,getAllTea, 
             newTea,
             deleteAllTea,
              getOneTea,
              newComment,
              deleteOneTea,uploadImg};
Kavishka Rajapakshe
  • 537
  • 1
  • 8
  • 23
  • see if this helps... I prefer multer for uploading files....https://medium.com/flutter-community/flutter-file-upload-using-multer-node-js-and-mongodb-5ba4da44453e –  Apr 11 '21 at 18:26
  • Also check out this simple solution: https://stackoverflow.com/a/72711178/10131684 – Ali Murtaza Jun 22 '22 at 07:25

1 Answers1

0

I can only provide insights on the Flutter-side of things. The way you've used image_picker to set the file to be uploaded and dio for the actual upload seems to be fine. What you'd want to do here is check the response from the server after the upload. Print response with debugPrint('Response: $response'); and see if there's any error thrown.

Omatt
  • 8,564
  • 2
  • 42
  • 144