flutter
/

GetX Navigation Arguments: Passing Data Between Screens

Last Sync: Today

On this page

14
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

flutter

GetX Navigation Arguments: Passing Data Between Screens

Introduction to Passing Data in GetX Navigation

GetX provides several powerful ways to pass data between screens. Whether you're using direct navigation (Get.to) or named routes (Get.toNamed), you can send data using arguments, dynamic path parameters, or even return results from a closed screen. This guide covers all these techniques with practical examples.

  1. Basic Arguments with Get.to

The simplest way to pass data is using the arguments parameter of Get.to(). This works with both widget‑based and named navigation.

DARTRead-only
1
// Sending data
Get.to(DetailsPage(), arguments: {'title': 'Hello', 'id': 42});

// Receiving data in the destination
class DetailsPage extends StatelessWidget {
  final args = Get.arguments;

  @override
  Widget build(BuildContext context) {
    String title = args['title'];
    int id = args['id'];
    return Text('$title - $id');
  }
}

  1. Named Routes with Arguments

When using named routes, you can also pass arguments using the arguments parameter. This is useful for sending any type of data without modifying the route definition.

DARTRead-only
1
// Navigation
Get.toNamed('/details', arguments: User(name: 'Alice', age: 30));

// Destination
class DetailsPage extends StatelessWidget {
  final user = Get.arguments as User;
  // ...
}

  1. Dynamic Parameters (Path Segments)

For values that should be part of the URL (like IDs), use dynamic parameters defined with : in the route definition. These are accessed via Get.parameters.

DARTRead-only
1
// Route definition
GetPage(
  name: '/user/:id',
  page: () => UserPage(),
);

// Navigation
Get.toNamed('/user/123');

// In UserPage
final userId = Get.parameters['id']; // '123'

  1. Query Parameters (URL Style)

GetX also automatically parses query strings. Combine with dynamic segments or use alone.

DARTRead-only
1
// Navigation with query parameters
Get.toNamed('/search?q=flutter&page=2');

// In SearchPage
final query = Get.parameters['q']; // 'flutter'
final page = Get.parameters['page']; // '2'

  1. Returning Results

To get a result back from a pushed screen, use await and then Get.back(result: value).

DARTRead-only
1
// In the source screen
final result = await Get.to(SelectionPage());
print('Selected: $result');

// In the destination screen
void selectItem(String item) {
  Get.back(result: item);
}

  1. Passing Complex Objects

You can pass any object, including custom classes, maps, or lists. Just ensure they are serializable if you need to preserve state across restarts.

DARTRead-only
1
class Product {
  final String id;
  final String name;
  final double price;
  Product(this.id, this.name, this.price);
}

// Send product
final product = Product('p1', 'Laptop', 999.99);
Get.toNamed('/product', arguments: product);

// Receive
final product = Get.arguments as Product;

  1. Passing Multiple Values

When you need to pass several values, you can use a map, a custom class, or a list. Maps are often convenient for simple scenarios.

DARTRead-only
1
// Using Map
Get.toNamed('/details', arguments: {
  'title': 'Welcome',
  'userId': 101,
  'isAdmin': true,
});

// Receiving
final title = Get.arguments['title'];
final userId = Get.arguments['userId'];
final isAdmin = Get.arguments['isAdmin'];

// Using a custom class (recommended for type safety)
Get.toNamed('/profile', arguments: UserProfile(name: 'John', age: 25));
final profile = Get.arguments as UserProfile;

  1. Accessing Arguments in onInit

If you're using a controller, you can access arguments inside onInit or onReady to initialize data.

DARTRead-only
1
class DetailsController extends GetxController {
  late final String id;

  @override
  void onInit() {
    super.onInit();
    id = Get.parameters['id'] ?? ''; // from path
    // or
    final args = Get.arguments;
    // use args...
  }
}

  1. Using GetView with Arguments

When using GetView, you still access arguments via Get.arguments inside the view or pass them to the controller via injection.

DARTRead-only
1
class DetailsView extends GetView<DetailsController> {
  @override
  Widget build(BuildContext context) {
    final id = Get.parameters['id'];
    return Text('ID: $id');
  }
}

Best Practices

  • Use typed classes for complex data – Avoid maps for large or structured data; use custom classes with named fields.
  • Validate arguments – Check if arguments are null and provide defaults to avoid crashes.
  • Use dynamic parameters for IDs – Makes URLs more meaningful and supports deep linking.
  • Return results with Get.back – Use await to handle user selections or form results.
  • Keep argument objects serializable – If you need to save the app state, ensure arguments can be serialized.

Common Mistakes

  • ❌ Accessing Get.arguments before they are set – Ensure you are in the destination screen. ✅ Use onInit or the build method after navigation.
  • ❌ Assuming the type of arguments without casting – This can cause runtime errors. ✅ Use as or is to check the type.
  • ❌ Forgetting to handle null – Get.arguments can be null. ✅ Always provide a fallback or check for null.
  • ❌ Mixing parameters and arguments – They serve different purposes; use parameters for URL segments, arguments for arbitrary data.

FAQ

  • Q: What is the difference between Get.arguments and Get.parameters?
    A: Get.parameters extracts dynamic path segments defined with : in the route name. Get.arguments is for any data you pass via the arguments parameter. They are completely separate.
  • Q: Can I pass a function as an argument?
    A: Yes, you can pass any object, including functions. But be careful about serialization if you need to restore state.
  • Q: How do I pass arguments with Get.offAllNamed?
    A: Just like Get.toNamed: Get.offAllNamed('/home', arguments: someData);
  • Q: Can I get arguments in a binding?
    A: Yes, bindings can access arguments if you pass them via the route. For example, in a custom binding you could read Get.arguments inside dependencies() if the route has already been accessed, but it's better to pass data through the controller's constructor.
  • Q: How do I handle missing parameters?
    A: Use Get.parameters['id'] ?? defaultValue to provide a fallback, and consider a 404 route for missing resources.
  • Q: Is there a way to pass data from a dialog back?
    A: Yes, Get.dialog returns a Future that completes when the dialog is closed. You can use Get.back(result: data) inside the dialog.

Conclusion

Passing data between screens is a fundamental part of app development. GetX simplifies this with multiple flexible options: arguments for arbitrary data, dynamic parameters for clean URLs, and result returning for callbacks. By following the patterns and best practices outlined here, you can build robust and maintainable navigation flows.

Try it yourself

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Navigation Arguments Demo',
      initialRoute: '/',
      getPages: [
        GetPage(name: '/', page: () => HomePage()),
        GetPage(name: '/details/:id', page: () => DetailsPage()),
        GetPage(name: '/profile', page: () => ProfilePage()),
      ],
    );
  }
}

class User {
  final String name;
  final int age;
  User(this.name, this.age);
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Passing Data')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 1. Arguments with Get.to
            ElevatedButton(
              onPressed: () {
                Get.to(
                  SimpleDetailsPage(),
                  arguments: {'message': 'Hello from Get.to'},
                );
              },
              child: Text('Get.to with arguments'),
            ),
            // 2. Named route with arguments
            ElevatedButton(
              onPressed: () {
                Get.toNamed('/profile', arguments: User('Alice', 30));
              },
              child: Text('Named route with arguments'),
            ),
            // 3. Dynamic parameters
            ElevatedButton(
              onPressed: () {
                Get.toNamed('/details/42');
              },
              child: Text('Dynamic parameter (ID: 42)'),
            ),
            // 4. Returning result
            ElevatedButton(
              onPressed: () async {
                final result = await Get.to(SelectionPage());
                Get.snackbar('Result', 'You selected: $result');
              },
              child: Text('Return result'),
            ),
          ],
        ),
      ),
    );
  }
}

class SimpleDetailsPage extends StatelessWidget {
  final args = Get.arguments;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Simple Details')),
      body: Center(
        child: Text('Message: ${args['message']}'),
      ),
    );
  }
}

class ProfilePage extends StatelessWidget {
  final user = Get.arguments as User;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Profile')),
      body: Center(
        child: Text('Name: ${user.name}, Age: ${user.age}'),
      ),
    );
  }
}

class DetailsPage extends StatelessWidget {
  final id = Get.parameters['id'];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Details')),
      body: Center(
        child: Text('Showing details for ID: $id'),
      ),
    );
  }
}

class SelectionPage extends StatelessWidget {
  final items = ['Apple', 'Banana', 'Orange'];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Select an item')),
      body: ListView.builder(
        itemCount: items.length,
        itemBuilder: (_, index) {
          return ListTile(
            title: Text(items[index]),
            onTap: () => Get.back(result: items[index]),
          );
        },
      ),
    );
  }
}

Test Your Knowledge

Q1
of 3

Which property is used to access dynamic path segments like '/user/:id'?

A
Get.arguments
B
Get.parameters
C
Get.pathParams
D
Get.segments
Q2
of 3

How do you return a result from a screen pushed with Get.to?

A
Get.return(result)
B
Get.back(result: value)
C
Get.result(value)
D
Get.close(value)
Q3
of 3

What is the recommended way to pass multiple values of different types?

A
Use separate route parameters
B
Use a Map or a custom class
C
Concatenate strings
D
Use global variables

Previous

getx route management

Next

getx dependency injection

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.