DEV Community

Cover image for Flutter: ๐Ÿ”ด How to Create and Read data || Future Builder || Partโ€Š-โ€Š3
Next Dev
Next Dev

Posted on โ€ข Edited on

2 1

Flutter: ๐Ÿ”ด How to Create and Read data || Future Builder || Partโ€Š-โ€Š3

Hey there ๐Ÿ‘‹, in this blog post, you will learn how to create and read the data in supabase using flutter packages (supabase_flutter).

If you understand Hindi ๐Ÿ‘‡


Firstly, you need to set up supabase in a flutter. So for that, you need to read this ๐Ÿ‘‡ article.
How to use supabase database in flutter || ๐Ÿ”ด Part โ€” 1

Step1: You need to make a table for the supabase database

Step2: Now you need to make a todo.dart file

import 'dart:convert';
class Todo {
final int?
id; // we are keeping the id to be nullable because we will use Todo type object as argument in create function.
// So there, we will not pass any id but the supabase will automatically generate it for us.
final String title;
Todo({
this.id,
required this.title,
});
Todo copyWith({
int? id,
String? title,
}) {
return Todo(
id: id ?? this.id,
title: title ?? this.title,
);
}
Map<String, dynamic> toMap() {
final result = <String, dynamic>{};
if (id != null) {
result.addAll({'id': id});
}
result.addAll({'title': title});
return result;
}
factory Todo.fromMap(Map<String, dynamic> map) {
return Todo(
id: map['id']?.toInt(),
title: map['title'] ?? '',
);
}
String toJson() => json.encode(toMap());
factory Todo.fromJson(String source) => Todo.fromMap(json.decode(source));
@override
String toString() => 'Todo(id: $id, title: $title)';
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is Todo && other.id == id && other.title == title;
}
@override
int get hashCode => id.hashCode ^ title.hashCode;
}
view raw todo.dart hosted with โค by GitHub

You can make models.dart file in the **model **folder.
export 'todo.dart';
Enter fullscreen mode Exit fullscreen mode

Step3: Now, you need to make a supabase_data_manager.dartโ€™ in the data folder in the utils folder. eg ๐Ÿ‘‡

Now you can use this code ๐Ÿ‘‡

import 'package:flutter_supabase_yt_1/models/models.dart'; // this is being used to import the todo.dart from models file.
import 'package:supabase_flutter/supabase_flutter.dart';
class SupabaseDataManager {
// create function which takes one argument of Todo
Future<PostgrestResponse<dynamic>> createData(Todo todo) async {
PostgrestResponse<dynamic> res = await Supabase.instance.client
.from('todos')
// here ๐Ÿ‘‡ you need to make todo.toMap() because we need to make Todo model to map --> eg Todo(title: 'This is first todo') -> {'title': 'This is first todo'}
.insert(todo.toMap())
.execute();
return res;
}
// read function
Future<PostgrestResponse<dynamic>> readData() async {
PostgrestResponse<dynamic> res = await Supabase.instance.client
.from('todos')
.select('id, title')
.execute();
return res;
}
}

Then you can make a utils.dart file in the utils folder.
// from data

export 'data/supabase_data_manager.dart';
Enter fullscreen mode Exit fullscreen mode

Now, you need to make a screens folder.

there are 3 files in the screens folder

  1. Create Screen โ€” โ€˜create_screen.dartโ€™

  2. Read Screen โ€” โ€˜read_screen.dartโ€™

  3. screens.dart for exporting the above screens

    import 'package:flutter/material.dart';
    import 'package:flutter_supabase_yt_1/models/models.dart';
    import 'package:flutter_supabase_yt_1/utils/utils.dart';
    import 'package:supabase_flutter/supabase_flutter.dart';
    class CreateScreen extends StatefulWidget {
    const CreateScreen({Key? key}) : super(key: key);
    @override
    State<CreateScreen> createState() => _CreateScreenState();
    }
    class _CreateScreenState extends State<CreateScreen> {
    TextEditingController todoController = TextEditingController();
    // instance
    SupabaseDataManager supabaseDataManager = SupabaseDataManager();
    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(title: const Text('Create')),
    body: Padding(
    padding: const EdgeInsets.all(20),
    child: Form(
    child: Column(
    children: [
    TextFormField(
    // controller
    controller: todoController,
    decoration: const InputDecoration(hintText: 'Todo'),
    ),
    ElevatedButton(onPressed: _createdData, child: const Text('Create'))
    ],
    )),
    ),
    );
    }
    Future _createdData() async {
    Todo todo = Todo(title: todoController.text);
    PostgrestResponse<dynamic> res = await supabaseDataManager.createData(todo);
    if (res.error != null) {
    // ignore: use_build_context_synchronously
    ScaffoldMessenger.of(context)
    .showSnackBar(SnackBar(content: Text(res.error!.message)));
    }
    // ignore: use_build_context_synchronously
    ScaffoldMessenger.of(context)
    .showSnackBar(SnackBar(content: Text('Created')));
    }
    }
    view raw create_screen.dart hosted with โค by GitHub
    import 'package:flutter/material.dart';
    import 'package:flutter_supabase_yt_1/models/models.dart';
    import 'package:flutter_supabase_yt_1/utils/utils.dart';
    import 'package:supabase_flutter/supabase_flutter.dart';
    class ReadScreen extends StatelessWidget {
    const ReadScreen({Key? key}) : super(key: key);
    @override
    Widget build(BuildContext context) {
    List<Todo>? _todos;
    SupabaseDataManager supabaseDataManager = SupabaseDataManager();
    Future<List<Todo>> readData() async {
    PostgrestResponse<dynamic> res = await supabaseDataManager.readData();
    if (res.error != null) {
    throw Exception(res.error!.message);
    }
    // Todo --> [Todo(id: 1, title: 'This'),Todo(id: 2, title: 'fafdaf')]
    // Map --> [{'id' : 1, 'title': 'This'},{'id' : 2, 'title': 'adfafaf'}]
    return (res.data as List<dynamic>).map((e) => Todo.fromMap(e)).toList();
    }
    return Scaffold(
    body: FutureBuilder(
    future: readData(),
    builder: ((context, snapshot) {
    if (snapshot.hasError) {
    return Center(child: Text(snapshot.error.toString()));
    } else if (snapshot.hasData) {
    return ListView.builder(
    itemCount: (snapshot.data! as List<Todo>).length,
    itemBuilder: ((BuildContext context, int index) {
    Todo todo = (snapshot.data! as List<Todo>)[index];
    return ListTile(
    title: Text(todo.title),
    );
    }),
    );
    }
    // until the data has been loaded, we will see this progess indicator.
    return const Center(child: CircularProgressIndicator());
    }),
    ),
    );
    }
    }
    view raw read_screen.dart hosted with โค by GitHub
export 'create_screen.dart';
export 'read_screen.dart';
view raw screens.dart hosted with โค by GitHub

Now, you can switch the screens in the main. dart.

Example

import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_supabase_yt_1/screens/screens.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// load env
await dotenv.load();
// initialise the app
String supabaseBaseUrl = dotenv.env['SUPABASE_BASE_URL'] ?? '';
String supabaseBaseKey = dotenv.env['SUPABASE_BASE_KEY'] ?? '';
await Supabase.initialize(url: supabaseBaseUrl, anonKey: supabaseBaseKey);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// you can place here CreateScreen() for viewing the create_screen screen
home: const ReadScreen(),
);
}
}
view raw main.dart hosted with โค by GitHub

Thanks for reading this blog. You can now try it out.

If you want to how to update and delete data ๐Ÿ‘‡ 

https://medium.com/@nextdevelopment1111/flutter-how-to-update-and-delete-data-in-supabase-part-4-675bf3f8fcbc

If you have any questions, feel free to ask here ๐Ÿ‘‡
Join the Next Dev Discord Server!

Sentry mobile image

App store rankings love fast apps - mobile vitals can help you get there

Slow startup times, UI hangs, and frozen frames frustrate usersโ€”but theyโ€™re also fixable. Mobile Vitals help you measure and understand these performance issues so you can optimize your appโ€™s speed and responsiveness. Learn how to use them to reduce friction and improve user experience.

Read full post โ†’

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

๐Ÿ‘‹ Kindness is contagious

Please leave a โค๏ธ or a friendly comment on this post if you found it helpful!

Okay