How to post an image to LARAVEL API in FLUTTER

DevOps

MOTOSHARE 🚗🏍️
Turning Idle Vehicles into Shared Rides & Earnings

From Idle to Income. From Parked to Purpose.
Earn by Sharing, Ride by Renting.
Where Owners Earn, Riders Move.
Owners Earn. Riders Move. Motoshare Connects.

With Motoshare, every parked vehicle finds a purpose. Owners earn. Renters ride.
🚀 Everyone wins.

Start Your Journey with Motoshare

Most online registration forms require the user to upload images. Adding an image upload feature to mobile apps can be challenging for some developers. This article will show you step by step how to upload images on your FLUTTER app to a LARAVEL RESTFUL API.

This article has two parts.

  • Laravel API
  • FLUTTER App

PART 1. LARAVEL API

Step 1: Create a new laravel project using composer. You can give it any name but in this case, we will name it ImageApi.

composer create-project --prefer-dist laravel/laravel ImageApi

Step 2: In the created project. Make a migration to create an images table.

php artisan make:migration create_images_table --create=images

Step 3: In the migration add the image fields title and url.

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateImagesTable extends Migration
{
    
    public function up()
    {
        Schema::create('images', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('url');
            $table->timestamps();
        });
    }
public function down()
    {
        Schema::drop('images');
    }
}Code language: HTML, XML (xml)

Step 4: Next, create a model called Image

php artisan make:model ImageCode language: CSS (css)

Step 5: In the model add the title fields and url fields in the fillable array.

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
    protected $table = 'images';
protected $fillable = [
        'title', 'url'
    ];
}Code language: HTML, XML (xml)

Step 6: Next, create a controller and name it ImageController.

php artisan make:controller ImageControllerCode language: CSS (css)

Step 7: To the ImageController. Add a function called addimage.

<?php
namespace App\Http\Controllers;
use App\Image;
use App\Http\Controllers\Controller;
class ImageController extends Controller
{
   
    public function addimage(Request $request)
    {
        $image = new Image;
        $image->title = $request->title;
        
            if ($request->hasFile('image')) {
            
            $path = $request->file('image')->store('images');
            $image->url = $path;
           }
        $image->save();
        return new ImageResource($image);
    }
}Code language: HTML, XML (xml)

Step 8: Finally in the api.php file in the routes folder

<?php
use Illuminate\Http\Request;
Route::resource('imageadd', 'Api\ImageController@addimage');Code language: HTML, XML (xml)

This will create an Api endpoint

<domain-name>/api/imageadd

The Flutter App will access this API endpoint.

PART 2: FLUTTER APP

Step 1: Create a fresh flutter App using this command.

$ flutter create Imageapp
$ cd Imageapp

Step 2: Add the image_picker package to your flutter using this command

$ flutter pub add image_picker

Step 3: Next, add the flutter http package to your project using this command

$ flutter pub add http

Step 4: In the lib folder of the Flutter App. Create two extra dart files.

  • the first one will be service.dart.
  • the second one will be image_upload.dart.

Step 5: In the service.dart file. Import the HTTP package and the dart:convert package to this file.

import 'package:http/http.dart' as http;
import 'dart:convert';Code language: JavaScript (javascript)

Step 6: Create a class called Service and inside it add a function called addImage. This function will make an HTTP POST request to The laravel endpoint we created in Part 1 of this article.

import 'package:http/http.dart' as http;
import 'dart:convert';
class Service {
Future<bool> addImage(Map<String, String> body, String filepath) async {
    String addimageUrl = '<domain-name>/api/imageadd';
    Map<String, String> headers = {
      'Content-Type': 'multipart/form-data',
    };
var request = http.MultipartRequest('POST', Uri.parse(addimageUrl))
      ..fields.addAll(body)
      ..headers.addAll(headers)
      ..files.add(await http.MultipartFile.fromPath('image', filepath));
var response = await request.send();
    if (response.statusCode == 201) {
      return true;
    } else {
      return false;
    }
  }
}Code language: JavaScript (javascript)

Step 7: In the image_upload.dart file. Create a stateful widget called ImageUpload

class ImageUpload extends StatefulWidget {
  ImageUpload({Key key}) : super(key: key);
@override
  _ImageUploadState createState() => _ImageUploadState();
}
class _ImageUploadState extends State<ImageUpload> {
  @override
  Widget build(BuildContext context) {
    return Container(
       
    );
  }
}Code language: JavaScript (javascript)

Step 8: Import the dart:io library, image_picker package, and material design package. Also, import the service.dart file you created.

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'service.dart';Code language: JavaScript (javascript)

Step 9: Inside the ImageUploadState class. Create the following variables.

Service service = Service();
final _addFormKey = GlobalKey<FormState>();
final _titleController = TextEditingController();
  
File _image;
final picker = ImagePicker();Code language: PHP (php)

Step 10: Next, add an asynchronous function that will be launching the phones’ image gallery. Call this function getImage.

Future getImage() async {
    final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
      } else {
        print('No image selected.');
      }
    });
  }Code language: JavaScript (javascript)

Step 11: Create another function to show the selected image to the user. Call it buildImage.

Widget _buildImage() {
    if (_image == null) {
      return Padding(
        padding: const EdgeInsets.fromLTRB(1, 1, 1, 1),
        child: Icon(
          Icons.add,
          color: Colors.grey,
        ),
      );
    } else {
      return Text(_image.path);
    }
  }Code language: JavaScript (javascript)

Step 12: Inside the main build function add a TextFormField widget. This is for the title of the image.

Widget build(BuildContext context) {
    
  Container(
    child: Column(
      children: <Widget>[
       Text('Image Title'),
         TextFormField(
            controller: _titleController,
            decoration: const InputDecoration(
              hintText: 'Enter Title',),
            validator: (value) {
              if(value.isEmpty) {
                 return 'Please enter image title';}
                     return null;
                        },),
                        ],
                  ),
            ),
      );
  }Code language: PHP (php)

Step 13: Next, add a button that will run the getImage function

Container(
    child: OutlineButton(
       onPressed: getImage, 
             child: _buildImage())),

Step 14: Then add a button that will post the title and the image to the server

Container(
     child: Column(
        children: <Widget>[
          RaisedButton(
            onPressed: () {
              if (_addFormKey.currentState.validate()) {
                _addFormKey.currentState.save();
                  Map<String, String> body = {
                   'title': _titleController.text,};
                    service.addImage(body, _image.path);
                     Navigator.pop(context);}},
            child: Text('Save',
               style: TextStyle(color: Colors.white)),
               color: Colors.blue,)],
                     ),
            )Code language: HTML, XML (xml)

Step 15: The final image_upload.dart file will look like this

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'service.dart';
class ImageUpload extends StatefulWidget {
  PostCreate();
@override
  _ImageUploadState createState() => _ImageUploadState();
}
class _ImageUploadState extends State<ImageUpload> {
  _ImageUploadState();
  
  Service service = Service();
final _addFormKey = GlobalKey<FormState>();
  final _titleController = TextEditingController();
  File _image;
  final picker = ImagePicker();
Future getImage() async {
    final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
      } else {
        print('No image selected.');
      }
    });
  }
@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Add Images'),
      ),
      body: Form(
        key: _addFormKey,
        child: SingleChildScrollView(
          child: Container(
            child: Card(
              child: Container(
                child: Column(
                  children: <Widget>[
                Container(
                  child: Column(
                    children: <Widget>[
                      Text('Image Title'),
                      TextFormField(
                        controller: _titleController,
                        decoration: const InputDecoration(
                           hintText: 'Enter Title',),
                        validator: (value) {
                          if (value.isEmpty) {
                            return 'Please enter title';
                             }
                            return null;
                                },
                              ),
                            ],
                          ),
                        ),
                       
                       
              Container(
                child: OutlineButton(
                  onPressed: getImage, 
                    child: _buildImage())),
              Container(
                 child: Column(
                   children: <Widget>[
                     RaisedButton(
                       onPressed: () {
                         if(_addFormKey.currentState.validate()) {
                           _addFormKey.currentState.save();
                           Map<String, String> body = {
                            'title': _titleController.text};
                          service.addImage(body, _image.path);}},
                       child: Text('Save'),
                                
                              )
                            ],
                          ),
                        ),
                      ],
                    ))),
          ),
        ),
      ),
    );
  }
Widget _buildImage() {
    if (_image == null) {
      return Padding(
       
        child: Icon(
          Icons.add,
          color: Colors.grey,
        ),
      );
    } else {
      return Text(_image.path);
    }
  }
}Code language: PHP (php)

Step 16: In the main.dart file import the image_upload.dart file. Then, add the ImageUpload widget.

import 'package:flutter/material.dart';
import 'image_upload.dart';
void main() {
  
  runApp(App());
}
class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
          
          child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: ImageUpload(),
      ),
    );
  }
}Code language: JavaScript (javascript)
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x