DEV Community

Ram Suraj
Ram Suraj

Posted on

Flutter and Kintone

Introduction to Kintone's REST API in Flutter

Kintone is a powerful platform for managing data and building custom applications, and in this article, we'll explore how to interact with Kintone's REST API using Flutter, a popular framework for building cross-platform mobile applications. We'll demonstrate how to fetch a record from a Kintone database and display them in a Flutter app.

Image description

Understanding the Note Class

To represent the data retrieved from Kintone, we define a Dart class called Note. This class has four properties: id, title, content, and modifiedTime. These properties correspond to the data fields we want to extract from Kintone records. The class also includes a constructor and a factory method for converting JSON data from Kintone into Note objects.

Image description

The record has a title and content and datetime.

Full Note Class Code

import 'dart:convert';
import 'package:http/http.dart' as http;

class Note {
  String id;
  String title;
  String content;
  String modifiedTime;

  Note(
      {required this.id,
      required this.title,
      required this.content,
      required this.modifiedTime});

  factory Note.fromJson(Map<String, dynamic> json) {
    return Note(
        id: json['record']['Record_number']['value'],
        title: json['record']['title']['value'],
        content: json['record']['content']['value'],
        modifiedTime: json['record']['updated']['value']);
  }
}

const String apiToken = ''; //API TOKEN
const String appId = ''; // APP ID for Database
const Map<String, String> getHeader = {
  // Api token Auth
  'X-Cybozu-API-Token': apiToken,
};

// fetch records from Kintone
Future<Note> fetchRecords() async {
  return await http
      .get(
          Uri.parse(
              'https://ramsurajcoding.kintone.com/k/v1/record.json?app=$appId&id=1'),
          headers: getHeader)
      .then(((response) {
    return Note.fromJson(jsonDecode(response.body));
  }));
}
Enter fullscreen mode Exit fullscreen mode

Fetching Records from Kintone

Now comes the core functionality: fetching records from Kintone. We use the http package to make an HTTP GET request to Kintone's API endpoint. In this example, we're requesting a specific record with ID 1 from the app specified by appId. The getHeader with the API token ensures proper authentication. When the response is received, we use the Note.fromJson factory method to convert the JSON data into a Note object.

Full Frontend Code

import 'package:country_city_state_kintone/constants/colors.dart';
import 'package:flutter/material.dart';
import '../models/note.dart';
import 'dart:math';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  late Future<Note> notes;

  @override
  void initState() {
    super.initState();
    notes = fetchRecords();
  }

  getRandomColor() {
    Random random = Random();
    return backgroundColors[random.nextInt(backgroundColors.length)];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blueGrey,
      body: Padding(
        padding: const EdgeInsets.fromLTRB(16, 40, 16, 0),
        child: Column(
          children: [
            Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
              const Text(
                'Notes',
                style: TextStyle(fontSize: 30, color: Colors.white),
              ),
              IconButton(
                  onPressed: null,
                  padding: const EdgeInsets.all(0),
                  icon: Container(
                    padding: const EdgeInsets.all(10),
                    width: 40,
                    height: 40,
                    decoration: BoxDecoration(
                        color: Colors.grey.withOpacity(0.8),
                        borderRadius: BorderRadius.circular(10)),
                    child: const Icon(
                      Icons.sort,
                      color: Colors.white,
                    ),
                  ))
            ]),
            Expanded(
                child: FutureBuilder<Note>(
              future: notes,
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  return Card(
                    elevation: 3,
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10)),
                    color: getRandomColor(),
                    child: ListTile(
                      title: RichText(
                          maxLines: 3,
                          overflow: TextOverflow.ellipsis,
                          text: TextSpan(
                              text: '${snapshot.data!.title} \n',
                              style: const TextStyle(
                                  color: Colors.black,
                                  fontWeight: FontWeight.bold,
                                  fontSize: 18,
                                  height: 1.5),
                              children: [
                                TextSpan(
                                    text: snapshot.data!.content,
                                    style: const TextStyle(
                                        color: Colors.black,
                                        fontWeight: FontWeight.normal,
                                        fontSize: 14,
                                        height: 1.5))
                              ])),
                      subtitle: Padding(
                        padding: const EdgeInsets.only(top: 8.0),
                        child: Text(
                          'Edited: ${snapshot.data!.modifiedTime}',
                          style: const TextStyle(
                              fontSize: 10,
                              fontStyle: FontStyle.italic,
                              color: Colors.black),
                        ),
                      ),
                      trailing: const IconButton(
                          onPressed: null,
                          icon: Icon(
                            Icons.delete,
                            color: Colors.grey,
                          )),
                    ),
                  );
                } else if (snapshot.hasError) {
                  return Text('$snapshot.error');
                }
                return const CircularProgressIndicator();
              },
            ))
          ],
        ),
      ),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

Conclusion

In this article, we've seen how to interact with Kintone's REST API in a Flutter application. We've defined a Note class to structure the data, set up API authentication, and demonstrated how to fetch records from a Kintone app.

This post is for the kintone contest
my account https://forum.kintone.dev/u/ram_suraj/

Top comments (1)

Collapse
 
ahandsel profile image
Genji

Thank you for submitting your project to the Kintone Customization Contest 2023!

Congratulations on your win!
We will be reaching out to you through the Kintone Developer Forum.