· hobby developer

Custom Routing Not Working

Custom Code

Hi,

I am trying to make my website URLs open a specific screen in my flutterflow app and not able to achieve this using custom action with code.

Ex - www.abc.com/challenges/123 and www.abc.com/profile/789 should open the 'challengeDetail' and 'otherProfile' flutterflow screens in the app. The page name and route are same in these 2 screens. 'challengeDetail' and 'otherProfile' accept 'cid' and 'userid' page parameters and are defined as strings.

My app entry screen is called 'router' and logged in page is 'home'.

In the 'router' page, i have added a text field called 'logText' which is bound to an App state variable 'routerLog'. Ideally i would like to see debug messages populated in this text field but that is not working so in code i have added an alert and a snackbox where i am able to see the debug messages.)

In my router page load Action Flow Editor, i am calling a custom action 'customRouter' with the code below.

What is happening -

  1. finalDestination is correctly detecting 'challengeDetail' and 'otherProfile'

  2. debug alert does show the challenge id and for profile. detected but the routing itself does not work - control is stuck on the 'router' page.

here is my code - any feedback/help figuring out why the redirect alone does not work?

// Automatic FlutterFlow imports
import '/backend/schema/structs/index.dart';
import '/actions/actions.dart' as action_blocks;
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!

Future<void> customRouter(BuildContext context) async {
  String logtext = '';
  int? userId;
  int? challengeId;

  void log(String message) {
    logtext = logtext + message + '\n';
    FFAppState().update(() {
      FFAppState().routerLog = String.fromCharCodes(
          FFAppState().routerLog.codeUnits +
              message.codeUnits +
              '\n'.codeUnits);
    });
  }

  try {
    // Get both the current URI and the window location
    final uri = GoRouter.of(context).routeInformationProvider.value.uri;
    final currentPath = uri.path;
    final fullUrl = Uri.base.toString();

    // Log all URL-related information for debugging
    log('Full URL: $fullUrl');
    log('Current path from GoRouter: $currentPath');
    log('URI host: ${uri.host}');
    log('URI path segments: ${uri.pathSegments}');

    // Extract the path from the full URL if needed
    String effectivePath = currentPath;
    if (currentPath == '/router' || currentPath == 'router') {
      // If we're on the router page, try to extract the intended path from the full URL
      final urlPath = Uri.parse(fullUrl).path;
      log('Extracted path from full URL: $urlPath');
      if (urlPath.contains('/profile/') || urlPath.contains('/challenges/')) {
        effectivePath = urlPath;
        log('Using path from full URL instead: $effectivePath');
      }
    }

    String finalDestination = '';

    // Parse the effective path
    if (effectivePath == '/' || effectivePath.isEmpty) {
      log('Root path detected');
      finalDestination = 'home';
    } else if (effectivePath.contains('/profile/')) {
      log('Profile path detected in: $effectivePath');
      // Extract user ID from the full URL if needed
      final profileRegExp = RegExp(r'/profile/(\d+)');
      final match = profileRegExp.firstMatch(effectivePath);

      if (match != null && match.groupCount >= 1) {
        try {
          userId = int.tryParse(match.group(1)!);
          if (userId != null) {
            log('Valid userId extracted: $userId');
            finalDestination = 'profile';
          } else {
            log('Invalid userId format');
            finalDestination = 'home';
          }
        } catch (e) {
          log('Error parsing userId: $e');
          finalDestination = 'home';
        }
      } else {
        log('No profile ID found in path');
        finalDestination = 'home';
      }
    } else if (effectivePath.contains('/challenges/')) {
      log('Challenge path detected in: $effectivePath');
      final challengeRegExp = RegExp(r'/challenges/(\d+)');
      final match = challengeRegExp.firstMatch(effectivePath);

      if (match != null && match.groupCount >= 1) {
        try {
          challengeId = int.tryParse(match.group(1)!);
          if (challengeId != null) {
            log('Valid challengeId extracted: $challengeId');
            finalDestination = 'challengeDetail';
          } else {
            log('Invalid challengeId format');
            finalDestination = 'home';
          }
        } catch (e) {
          log('Error parsing challengeId: $e');
          finalDestination = 'home';
        }
      } else {
        log('No challenge ID found in path');
        finalDestination = 'home';
      }
    } else {
      log('Unknown path, redirecting to home');
      finalDestination = 'home';
    }

    log('Determined final destination: $finalDestination');

    if (!context.mounted) {
      log('Context is not mounted, cannot navigate');
      return;
    }

    // Display debug information
    await showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Debug Information'),
          content: SingleChildScrollView(
            child: Text(logtext),
          ),
          actions: <Widget>[
            TextButton(
              child: Text('Continue'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );

    if (!context.mounted) return;

    switch (finalDestination) {
      case 'home':
        log('Navigating to home page...');
        context.pushNamed(
          'home',
          extra: <String, dynamic>{},
        );
        break;

      case 'profile':
        log('Navigating to profile page...');
        if (userId != null) {
          context.pushNamed(
            'otherProfile',
            queryParameters: {'userid': userId.toString()},
            extra: <String, dynamic>{},
          );
        } else {
          log('Error: userid is null');
        }
        break;

      case 'challengeDetail':
        log('Navigating to challenge detail page...');
        if (challengeId != null) {
          context.pushNamed(
            'challengeDetail',
            queryParameters: {'cid': challengeId.toString()},
            extra: <String, dynamic>{},
          );
        } else {
          log('Error: cid is null');
        }
        break;
    }

    log('Navigation completed');
  } catch (e, stackTrace) {
    final errorMsg =
        'Error: ${e.toString()}\nStack trace: ${stackTrace.toString()}\n';
    FFAppState().update(() {
      FFAppState().routerLog = String.fromCharCodes(
          FFAppState().routerLog.codeUnits + errorMsg.codeUnits);
    });

    if (context.mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Navigation error: ${e.toString()}'),
          duration: Duration(seconds: 5),
        ),
      );
    }
  }
}
What have you tried so far?

explained above

Did you check FlutterFlow's Documentation for this topic?
No
1
1 reply