Gunakan ← → untuk navigasi
Klik topik mana saja untuk langsung melompat ke materinya.
Kamu sudah kenal Flutter (alat untuk membuat aplikasi), Dart (bahasanya), dan kenapa Dart dipakai: cepat, modern, dan satu kode untuk Android & iOS.
Sekarang kita masuk ke cara menulis kode Dart: menyimpan data, mengambil keputusan, mengulang aksi, dan membuat fungsi. Diakhiri membuat Kalkulator!
BAB 1 adalah melihat denah & memahami alat. BAB 2 adalah memegang batu bata pertama. Variable, tipe data, dan fungsi adalah bata yang menyusun seluruh aplikasi.
Variable itu seperti kotak berlabel. Setiap kotak punya nama dan bisa diisi sesuatu. Kalau kamu butuh isinya, cukup sebut nama kotaknya.
Contoh: kotak bernama nama berisi tulisan "Rifqi".
// Membuat kotak (variable) bernama 'nama'
String nama = "Rifqi";
int umur = 16;
// Mengambil isi kotak
print(nama); // RifqiString adalah tipe data untuk teks — huruf, kata, kalimat. Seperti label nama yang ditempel di barang. Selalu ditulis di dalam tanda kutip "...".
String sekolah = "SMK Negeri 1";
String hobi = "Coding";
// Menggabungkan teks (interpolasi)
print("Aku suka $hobi di $sekolah");int = bilangan bulat (1, 50, -7), seperti jumlah buku.
double = bilangan desimal (1.5, 3.14), seperti angka di timbangan digital.
int jumlahSiswa = 32;
double tinggiBadan = 170.5;
double rataRata = 88.75;int bertambah/berkurang 1
bool hanya punya 2 nilai: true (benar/nyala) atau false (salah/mati). Seperti saklar lampu — tidak ada di tengah.
bool sudahLulus = false;
bool hadir = true;
if (hadir) print("Absen tercatat");List adalah wadah terurut yang dapat menyimpan banyak nilai sekaligus dalam satu variabel. Setiap elemen memiliki nomor urut (indeks) dimulai dari 0.
Bayangkan loker bernomor. Loker [0] berisi "Apel", Loker [1] berisi "Pisang". Jika kamu ingin mengambil isinya, kamu panggil nomor lokernya.
List<String> buah = ["Apel", "Pisang", "Jeruk"];
// Akses elemen dengan [indeks]
print(buah[0]); // Apel
print(buah[1]); // Pisang
// Properti Utama
print(buah.length); // 3 (Total data)
print(buah.first); // Apel
print(buah.last); // Jeruk
print(buah.isEmpty); // falseMethod untuk memasukkan data baru ke dalam List di posisi akhir atau di tengah indeks spesifik.
Memasukkan 1 elemen baru di ujung paling akhir list.
💻 Sintaksbuah.add("Ceri");
Panjang list bertambah 1 (`length + 1`). Data baru mendapat nomor indeks paling akhir.
Menggabungkan sekumpulan data dari list lain sekaligus di paling akhir.
💻 Sintaksbuah.addAll(["Ceri", "Melon"]);
Lebih cepat dan ringkas daripada memanggil `.add()` secara berulang-ulang.
Menyelipkan elemen di nomor indeks tertentu tanpa menimpa/menghapus data lama.
💻 Sintaksbuah.insert(1, "Mangga");
Data lama di posisi indeks tersebut dan seterusnya otomatis tergeser mundur 1 posisi (+1 indeks).
Method untuk menghapus elemen berdasarkan nilai, posisi indeks, atau mengosongkan list.
Mencari dan menghapus kemunculan pertama elemen berdasarkan namanya.
💻 Sintaksbool sukses = buah.remove("Pisang");
Mengembalikan true jika data ditemukan & berhasil dihapus, atau false jika data tidak ada.
Menghapus elemen di nomor posisi indeks tertentu.
💻 SintaksString terhapus = buah.removeAt(0);
Mengembalikan objek yang dihapus ("Apel"). Elemen setelahnya tergeser maju 1 posisi (-1 indeks).
Menghapus semua elemen dari list tanpa mengikis variabelnya.
💻 Sintaksbuah.clear();
List menjadi kosong total (`isEmpty == true`).
Method untuk mengecek keberadaan data, mencari indeks, dan mengurutkan posisi elemen.
Cek apakah suatu nilai ada di dalam list (untuk pengkondisian `if`).
💻 Sintaksbool ada = buah.contains("Apel");
Mengembalikan nilai boolean `true` atau `false` tanpa mengubah isi list.
Mencari nomor indeks lokasi ditemukannya suatu nilai.
💻 Sintaksint idx = buah.indexOf("Pisang");
Mengembalikan integer lokasi indeks. Angka `-1` menandakan data tidak ada di list.
`sort()` merapikan urutan (A-Z / 1-9). `reversed` membalik urutan.
💻 Sintaksbuah.sort(); | List b = buah.reversed.toList();
`sort()` mengubah list asli (*mutate*). `.reversed` mengembalikan `Iterable` baru.
Uji coba langsung semua method List yang dipelajari dan lihat hasil eksekusinya secara real-time!
Map menyimpan data berpasangan Key (Kunci) → Value (Nilai). Kunci bersifat unik dan dipakai untuk mengakses nilainya.
Kamu tidak mencari nomor telepon ibu berdasarkan nomor urut antrean, tapi berdasarkan **nama kuncinya ("Ibu")**.
Map<String, String> kontak = {
"Ibu": "0812-111",
"Guru": "0813-222"
};
// Akses nilai menggunakan [Key]
print(kontak["Ibu"]); // 0812-111
// Properti Utama Map
print(kontak.length); // 2
print(kontak.keys); // (Ibu, Guru)
print(kontak.values); // (0812-111, 0813-222)Method untuk memasukkan data baru atau memperbarui nilai dari kunci yang sudah ada.
Membuat pasangan data baru, atau **menimpa (overwrite)** nilai lama jika Key sudah pernah dibuat.
💻 Sintaksstok["Pensil"] = 5;
Operator `[]=` otomatis mendeteksi keberadaan Key. Sangat praktis & fleksibel.
Melindungi data lama agar tidak sengaja tertimpa jika Key sudah ada sebelumnya.
💻 Sintakskontak.putIfAbsent("Ibu", () => "0999");
Aman dari ketidaksengajaan *overwriting* nilai variabel penting.
Method untuk menghapus entry kunci-nilai, mengecek kunci, dan mengosongkan Map.
Menghapus pasangan Key-Value dari Map berdasarkan nama kuncinya.
💻 SintaksString? val = kontak.remove("Guru");
Mengembalikan nilai (*Value*) dari Key yang terhapus (misal `"0813"`). Jika Key tak ada → mengembalikan `null`.
Memeriksa ketersediaan Kunci atau Nilai tertentu di dalam Map.
💻 Sintaksbool ada = kontak.containsKey("Ibu");
Mengembalikan `bool`. `containsKey` diproses sangat cepat oleh sistem internal Dart.
Uji coba langsung semua method Map yang dipelajari dan lihat perubahan tabel kuncinya!
Set adalah tipe data koleksi khusus di Dart yang **menolak data duplikat secara otomatis**.
// Deklarasi Set menggunakan kurung kurawal {}
Set<String> warna = {"Merah", "Hijau", "Merah"};
print(warna); // {"Merah", "Hijau"} -> "Merah" ke-2 ditolak!
// Method utama Set
bool ditambahkan = warna.add("Merah"); // false (duplikat)
warna.remove("Hijau");
print(warna.contains("Merah")); // trueKetik nama item sama 2x untuk uji filter duplikat!
| Kriteria | List <T> | Map <K, V> | Set <T> |
|---|---|---|---|
| Struktur | Urutan Indeks `[0, 1, 2]` | Pasangan Key → Value | Kumpulan Nilai Unik |
| Duplikat | Boleh ada data duplikat | Key Wajib Unik, Value Bebas | TIDAK BOLEH Duplikat |
| Akses Data | `list[0]` | `map["Ibu"]` | `set.contains("item")` |
| Penggunaan | Antrean, daftar belanja | Kontak, profil, kamus | Kumpulan ID unik, tag unik |
Operator adalah simbol untuk mengolah data: berhitung, membandingkan, dan logika.
+ - * / % (sisa bagi)
== != > < >= <= → hasil bool
&& (dan) || (atau) ! (bukan)
Struktur keputusan paling dasar. Kode di dalam blok if HANYA dijalankan jika kondisi bernilai true. Jika false, kode dilewati!
Ketika menempelkan kartu: JIKA (if) saldo ≥ 10.000, maka palang terbuka. Jika saldo tidak cukup, tidak ada aksi pembukaan pintu.
int saldo = 15000;
// Pengecekan Tunggal (Hanya 'if')
if (saldo >= 10000) {
print("Silakan Masuk ✅");
}
print("Perjalanan dilanjutkan...");Digunakan ketika ada 2 kemungkinan keputusan. Jika syarat if terpenuhi (true), jalankan blok A. Jika tidak (false), jalankan blok else (blok B).
Komputer memilih salah satu dari 2 jalan: JIKA nilai ≥ 75 → LULUS, SELAIN ITU (else) → REMIDI. Tidak mungkin dua-duanya berjalan.
int nilai = 80;
if (nilai >= 75) {
print("LULUS 🎉");
} else {
print("REMIDI 📕");
}Digunakan ketika ada banyak pilihan kondisi (> 2). Dart mengecek dari atas ke bawah. Begitu ada kondisi yang true, blok tersebut dijalankan dan sisanya diabaikan!
Evaluasi berjenjang: Cek dulu apakah nilai ≥ 90 (Grade A). Jika tidak, cek apakah ≥ 80 (Grade B), dst. Jika semua syarat di atas false, masuk ke else terakhir (Grade E).
int nilai = 85;
if (nilai >= 90) {
print("Grade A 🌟");
} else if (nilai >= 80) {
print("Grade B 👍");
} else if (nilai >= 70) {
print("Grade C 👌");
} else {
print("Grade E ❌");
}Bentuk singkat (shorthand / shortcut) dari if-else sederhana. Memungkinkan kita mengambil keputusan dan mengembalikan nilai hanya dalam 1 baris kode!
Daripada menulis 5 baris kode if-else hanya untuk menetapkan 1 variabel, gunakan Operator Ternary agar kode jauh lebih bersih & rapi!
// ❌ Cara Biasa (5 Baris)
String status;
if (nilai >= 75) {
status = "LULUS";
} else {
status = "REMIDI";
}
// ✅ Cara Ternary (Ringkas 1 Baris!)
String status = (nilai >= 75) ? "LULUS" : "REMIDI";Tekan tombol channel → langsung pindah ke channel itu. switch memilih satu aksi dari banyak pilihan berdasarkan satu nilai. Lebih rapi daripada banyak if.
int hari = 1;
switch (hari) {
case 1: print("Senin"); break;
case 2: print("Selasa"); break;
default: print("Akhir pekan");
}for dipakai saat kita tahu berapa kali harus mengulang. Seperti baling-baling yang berputar persis 5 kali lalu berhenti.
for (int i = 1; i <= 5; i++) {
print("Putaran ke-$i");
}while mengulang selama syarat masih benar. Alarm terus berbunyi selama belum dimatikan. Berhenti begitu syarat jadi false.
int snooze = 0;
while (snooze < 3) {
print("Alarm bunyi! 🔔");
snooze++; // dekati syarat berhenti
}⚠️ Jangan lupa ubah kondisi di dalam loop, atau loop tak akan berhenti (infinite loop)!
do while menjalankan aksi minimal SEKALI dulu, baru cek syarat. Kamu pasti minum dosis pertama, baru cek "perlu lagi tidak?".
int dosis = 0;
do {
print("Minum obat 💊");
dosis++;
} while (dosis < 3);Sebelumnya kita membuat program dengan data statis:
String nama = "Rifqi";
print("Halo $nama");Masalahnya: setiap ingin mengganti nama, kita harus mengubah kode program. Aplikasi nyata (seperti form login, kalkulator, pendaftaran) membutuhkan input dari pengguna saat program berjalan.
Dart menyediakan library bawaan bernama dart:io untuk menangani Input/Output. Kita harus meng-import library ini di baris paling atas kode kita:
import 'dart:io';Dengan meng-import dart:io, program kita bisa menggunakan fitur input keyboard (stdin) dan output konsol (stdout).
Untuk membaca apa yang diketik oleh user di keyboard, gunakan perintah:
stdin.readLineSync()Perintah ini akan menghentikan sementara (pause) program, menunggu user mengetik sesuatu lalu menekan tombol Enter.
Karena user bisa saja langsung menekan Enter tanpa mengetik apa-apa, maka hasil input disimpan dalam tipe data yang boleh kosong (nullable String): String?
import 'dart:io';
void main() {
print("Masukkan nama:");
// Menyimpan input ke variabel nama
String? nama = stdin.readLineSync();
print("Halo $nama");
}stdin.readLineSync() → 📦 Variabel → 🖥️ Program
Perlu diingat bahwa stdin.readLineSync() selalu menghasilkan teks (String). Jika user mengetik 10, Dart akan menerimanya sebagai teks "10", bukan angka 10. Kita tidak bisa menjumlahkannya langsung!
Kita harus mengubah teks tersebut menjadi angka menggunakan parse():
int.parse()double.parse()Karena stdin.readLineSync() bisa bernilai null (kosong), sedangkan int.parse() membutuhkan teks yang pasti ada. Tanda ! (Null Assertion Operator) digunakan untuk meyakinkan Dart: "Saya jamin input ini tidak kosong!"
// Membaca input angka bulat
int angka = int.parse(stdin.readLineSync()!);
// Membaca input desimal
double tinggi = double.parse(stdin.readLineSync()!);Rasakan bagaimana program Dart menerima input runtime dan memprosesnya secara dinamis!
print("Masukkan nama:");
String? nama = stdin.readLineSync();
print("Halo $nama");int a = int.parse(stdin.readLineSync()!);
int b = int.parse(stdin.readLineSync()!);
print("Hasil = ${a + b}");Function (fungsi) adalah blok kode terpisah yang dirancang untuk melakukan tugas tertentu. Seperti mesin cuci otomatis: kamu cukup menekan tombol, dan mesin akan bekerja tanpa kamu harus mencuci manual setiap kali.
Dalam programming, kita sering menulis kode yang sama berulang-ulang. Daripada melakukan itu, kita membungkus kode tersebut di dalam sebuah Function. Ketika kita membutuhkannya, kita cukup memanggil namanya.
Konsep ini dikenal sebagai DRY (Don't Repeat Yourself) — prinsip utama untuk menulis kode yang bersih dan profesional.
Bayangkan jika kamu harus menyapa 3 siswa yang berbeda. Tanpa function, kamu harus menulis print berulang-ulang:
print("Halo Rifqi, selamat belajar Dart!");
print("Halo Budi, selamat belajar Dart!");
print("Halo Ani, selamat belajar Dart!");Bagaimana kalau ada 100 siswa? Atau kalau kalimat sapaannya ingin diganti? Kamu harus mengubah 100 baris kode satu per satu!
Dengan function, kita membungkus pola kalimat sapaan tersebut:
void sapaSiswa(String nama) {
print("Halo $nama, selamat belajar Dart!");
}Jika ingin mengubah kalimatnya, kamu cukup mengedit di dalam function saja, dan seluruh pemanggilan akan otomatis berubah!
Mari kita bedah anatomi dari sebuah function di Dart:
int tambah(int a, int b) {
return a + b;
}Sama seperti mesin: masukkan data → diolah → keluar hasil.
Banyak pemula bingung karena kodenya tidak menghasilkan apa-apa. Ingat prinsip ini:
Membuat function itu seperti membeli mesin cuci. Mesin tidak akan mencuci bajumu sebelum kamu menekan tombol Start (Memanggilnya).
void salam() {
print("Halo Dart");
}Function ini tidak memerlukan input apapun untuk berjalan. Kata kunci void menandakan bahwa function ini tidak menghasilkan/mengembalikan data (*no return value*), melainkan langsung melakukan aksi (seperti melakukan print).
void halo() {
print("Hello Dart");
}
// Cara Memanggil:
halo();Klik tombol di bawah untuk menjalankan function halo()
Parameter adalah variabel penampung data input yang diletakkan di dalam kurung (String nama). Function akan memproses nilai ini secara dinamis sesuai dengan argumen yang dilewatkan saat pemanggilan.
void halo(String nama) {
print("Halo $nama");
}
// Cara Memanggil:
halo("Rifqi");Masukkan nama kamu di bawah, lalu panggil functionnya!
Jika kita ingin function menghasilkan suatu nilai yang bisa kita simpan ke variabel atau kita olah lagi, kita wajib menggunakan return type di awal deklarasi dan kata kunci return di akhir function.
int kali(int a, int b) {
return a * b;
}
// Cara Memanggil:
print(kali(5, 2)); // Output: 10Uji perhitungan perkalian menggunakan function kali(a, b):
Arrow Function adalah alternatif penulisan function yang lebih ringkas menggunakan operator panah (=>). Jika isi function hanya 1 baris return, kurung kurawal {} dan kata kunci return bisa dihilangkan (implicit return).
// Sintaks Standar Arrow Function
const tambah = (a, b) => {
return a + b;
};
console.log(tambah(5, 3)); // Output: 8
// Bentuk Singkat (Implicit Return)
const tambahSingkat = (a, b) => a + b;
console.log(tambahSingkat(10, 20)); // Output: 30Uji coba penambahan angka menggunakan Arrow Function (a, b) => a + b
Arrow function memberikan fleksibilitas saat mendefinisikan parameter:
().() bersifat opsional dan boleh dihilangkan!// 5. Tanpa Parameter
const hello = () => {
console.log("Hello Javascript");
};
hello(); // Output: Hello Javascript
// 6. Satu Parameter (Tanpa Kurung)
const nama = name => {
console.log(name);
};
nama("Rifqi"); // Output: RifqiUji pemanggilan tanpa parameter atau 1 parameter
Arrow function paling sering digunakan sebagai callback function pada method array seperti forEach, map, filter, dan reduce karena penulisannya yang sangat bersih dan ringkas.
const angka = [1, 2, 3, 4, 5];
// Menggunakan Arrow Function pada forEach:
angka.forEach(item => {
console.log(item);
});
/* Output:
1
2
3
4
5
*/Array: [1, 2, 3, 4, 5]
Nested Function adalah function yang berada di dalam function lain. Function bagian dalam (dalam()) hanya dapat dipanggil dan diakses di dalam scope function luar (luar()).
function login() {
console.log("Proses Login");
// Nested Function (Function Dalam)
function validasi() {
console.log("Validasi User");
}
validasi(); // Memanggil function validasi() di dalam login()
}
login();
/* Output:
Proses Login
Validasi User
*/Nested function dapat mengakses variabel & parameter dari function pembungkusnya. Selain itu, nested function juga bisa ditulis menggunakan sintaks Arrow Function.
// 9. Nested Function dengan Parameter
function hitungDiskon(harga) {
function diskon() {
return harga * 0.1; // 10% diskon
}
return harga - diskon();
}
console.log(hitungDiskon(100000)); // Output: 90000
// 10. Nested Arrow Function
const aplikasi = () => {
const database = () => {
console.log("Mengakses Database");
};
database();
};
aplikasi(); // Output: Mengakses DatabaseMasukkan harga belanja untuk dihitung diskon 10% secara internal:
| Function Biasa | Arrow Function |
|---|---|
Keyword function |
Menggunakan panah => |
| Syntax lebih panjang | Syntax lebih pendek |
Memiliki this sendiri |
Tidak punya this sendiri |
| Cocok untuk method object | Cocok untuk callback |
// Function Biasa:
function totalBelanja(harga, jumlah) {
return harga * jumlah;
}
// Arrow Function:
const totalBelanja = (harga, jumlah) => harga * jumlah;
console.log(totalBelanja(5000, 3)); // Output: 15000Hitung total belanja dengan Function Biasa vs Arrow Function
Cobalah untuk membuat function-function berikut di editor Dart-mu:
0.5 * alas * tinggi💡 Petunjuk: panggil semua function tersebut di dalam method void main() untuk melihat hasilnya.
null artinya "kotak kosong / belum ada isi". Kalau kita pakai isi kotak yang ternyata kosong → aplikasi error/crash! Dart melindungi kita dengan Null Safety.
// Tanda ? = boleh kosong (nullable)
String? nama = null;
// ?? = nilai cadangan jika null
print(nama ?? "Tanpa Nama");
// Tanpa ? = WAJIB ada isi (aman)
String kota = "Jakarta";Gabungan dari semua yang dipelajari: variable, tipe data, operator, function, dan if-else. Coba langsung!
Uji: 15 + 27 = 42 ✓
Buat program Dart yang menyimpan biodata dirimu menggunakan tipe data yang tepat:
💡 Petunjuk: String nama = "..."; lalu print("Nama: $nama");
Buat program yang menentukan status siswa berdasarkan nilai dengan if-else:
💡 Petunjuk: urutkan kondisi dari nilai tertinggi ke terendah.
Kembangkan Mini Project Kalkulator (slide 40) dengan menambah fitur:
💡 Kumpulkan file .dart + screenshot output. Deadline: 1 minggu.
Variable, String, int, double, bool, List, Map, Set untuk menyimpan informasi.
Operator, if-else, else-if, ternary & switch untuk mengambil keputusan.
for, while, do-while untuk mengulang aksi.
Function untuk membungkus proses agar bisa dipakai ulang.
String? dan ?? untuk mencegah error data kosong.
Kalkulator: bukti kamu bisa menggabung semuanya!
Selanjutnya kamu akan belajar Class & Object: cara membuat "cetakan" untuk data yang kompleks, seperti membuat blueprint Mobil lalu mencetak banyak mobil. Sampai jumpa di BAB 3! 🚀