"You don't need to be a Dart expert to build Flutter apps. But you do need to understand what you're reading. This guide gives you exactly that — no more, no less."
Dart is Google's programming language, designed in 2011 specifically to be easy to learn and fast to compile. If you know any C-family language (Java, C#, JavaScript, Kotlin), Dart will feel immediately familiar. If you're completely new to programming, Dart is one of the friendliest languages to start with.
Variables and Types
Dart is a statically typed language — every variable has a type. But Dart can also infer types automatically using var.
// Explicit type declaration
String name = 'Raushan';
int age = 32;
double salary = 85000.50;
bool isMCT = true;
// Type inference — Dart figures out the type from the value
var topicName = 'Flutter Getting Started'; // Dart infers: String
var lessonCount = 6; // Dart infers: int
var price = 0.0; // Dart infers: double
// Constants — value never changes
const pi = 3.14159;
final String city = 'Noida'; // final = set once, can't change after
const means the value is known at compile time (like π). final means the value is set once at runtime and never changes after (like a user's name after login).
Null Safety — Dart's Most Important Feature
Dart has sound null safety — by default, variables cannot be null. This prevents the most common runtime crash in programming: the null pointer exception.
// This will NOT compile — String cannot be null by default
String name = null; // ❌ Error
// To allow null, add ? after the type
String? name = null; // ✅ This is fine — name can be null
// Null-aware operators
print(name?.length); // Only calls .length if name is not null
print(name ?? 'Guest'); // If name is null, use 'Guest' instead
Functions
// Basic function
String greet(String name) {
return 'Hello, $name!';
}
// String interpolation — use $ to embed variables
String fullGreeting(String name, String role) {
return 'Hello, $name! You are a $role.'; // $ for variable, ${} for expression
}
// Arrow function — single expression, no need for {} and return
String greetShort(String name) => 'Hello, $name!';
// Optional parameters — use [] for positional, {} for named
void printTopic(String title, [int? lessons, bool? free]) {
print('$title — ${lessons ?? 0} lessons — Free: ${free ?? false}');
}
// Named parameters — caller must use the name
void createUser({required String name, int age = 0}) {
print('User: $name, Age: $age');
}
// Calling named parameters:
createUser(name: 'Raushan', age: 32);
createUser(name: 'Student'); // age defaults to 0
Lists, Maps and Sets
// List (like arrays in other languages)
List<String> topics = ['Flutter', 'Azure', 'Power BI'];
var numbers = [1, 2, 3, 4, 5]; // Dart infers List<int>
topics.add('Blazor');
topics.remove('Azure');
print(topics.length); // 3
print(topics[0]); // 'Flutter'
print(topics.contains('Power BI')); // true
// Map (key-value pairs — like Dictionary in C# or Object in JS)
Map<String, int> examScores = {
'PL-300': 750,
'AZ-204': 820,
'AZ-104': 780,
};
print(examScores['PL-300']); // 750
examScores['AI-102'] = 800; // Add new entry
// Iterating
for (var topic in topics) {
print(topic);
}
examScores.forEach((exam, score) {
print('$exam: $score');
});
Classes and Objects — OOP in Dart
Flutter is built entirely with classes. Everything you use in Flutter — Text, Button, Column — is a class. Understanding Dart classes is essential.
class Topic {
// Properties
String title;
int lessonCount;
bool isFree;
// Constructor
Topic(this.title, this.lessonCount, {this.isFree = false});
// Named constructor
Topic.free(String title) : this(title, 0, isFree: true);
// Method
String getSummary() {
return '$title — $lessonCount lessons — ${isFree ? "Free" : "Paid"}';
}
}
// Using the class
var flutter = Topic('Flutter Getting Started', 6, isFree: true);
print(flutter.getSummary());
// Output: Flutter Getting Started — 6 lessons — Free
// Inheritance
class PremiumTopic extends Topic {
double price;
PremiumTopic(String title, int lessons, this.price)
: super(title, lessons, isFree: false);
@override
String getSummary() {
return super.getSummary() + ' — ₹$price';
}
}
Async / Await — Handling Asynchronous Code
Almost everything in a Flutter app that involves waiting — network requests, file reading, database queries — is asynchronous. Dart uses Future and async/await for this.
// A Future represents a value that will be available later
Future<String> fetchUserName() async {
// Simulate a network request taking 2 seconds
await Future.delayed(Duration(seconds: 2));
return 'Raushan Ranjan';
}
// Calling an async function
void main() async {
print('Fetching user...');
String name = await fetchUserName();
print('User: $name');
// Output after 2 seconds: User: Raushan Ranjan
}
// Real-world example — HTTP request pattern
Future<List<Topic>> loadTopics() async {
try {
final response = await http.get(Uri.parse('https://api.example.com/topics'));
if (response.statusCode == 200) {
// parse JSON and return List<Topic>
return parseTopics(response.body);
} else {
throw Exception('Failed to load topics');
}
} catch (e) {
print('Error: $e');
return [];
}
}
await can only be used inside an async function. Whenever you see await in Flutter code, you know it's waiting for something (usually network or disk I/O).
What You Will See in Flutter Code
Here is a minimal Flutter widget using everything above. Read it — you should understand all of it now:
import 'package:flutter/material.dart';
class TopicCard extends StatelessWidget {
final String title; // final property
final int lessonCount;
final bool isFree;
// Named constructor with required and optional params
const TopicCard({
super.key,
required this.title,
required this.lessonCount,
this.isFree = false, // optional, defaults to false
});
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(title), // String
Text('$lessonCount lessons'), // interpolation
Text(isFree ? 'Free' : 'Paid'), // ternary
],
),
),
);
}
}
Dart Quick Reference
- Types: String, int, double, bool, List, Map — Dart infers with
var - Null safety: Add
?to allow null — use??for fallback values - String interpolation:
'Hello $name'or'${expression}' - Functions: typed params, optional with
[], named with{}, arrow with=> - Classes: constructor with
this.property, inheritance withextends, override with@override - Async:
Future<T>return type,asynckeyword on function,awaitto wait