Search code examples
flutterdartaqueduct

Register to aqueduct backend from Flutter frontend


I'm having a bit of difficulty with registering to aqueduct backend from my Flutter frontend

Here is my code in my frontend:

  Future<void> signUp(String email, String password) async {
    final body = "username:$email,password:$password"; //<- return request entity could not be decoded
    //final body = {"username": email, "password": password}; //<- return bad state: Cannot set the body fields of Request with content-type "application/json"

    try {
      final http.Response response = await http.post(
          "http://localhost:8888/register",
          headers: {"Content-Type": "application/json"},
          body: body);
      final jsonResponse = json.decode(response.body);
      if (jsonResponse["error"] != null) {
        throw HttpException(jsonResponse["error"]);
      }
    } catch (error) {
      throw error;
    }
  }

There must be some silly mistake. I believe it is with formatting body so I tried 2 options and both throw different http exception (as in comment).


Solution

  • Here is an example of connecting to an Aqueduct server from a Flutter client. (This isn't really a server question, though, since the client and server are independent of each other.)

    Here is an example of registering:

    void _register(String email, String password) async {
      Map<String, String> headers = {"Content-type": "application/json"};
      final jsonString = '{"username":"$email", "password":"$password"}';
      Response response = await post(YOUR_URL_HERE, headers: headers, body: jsonString);
      print('${response.statusCode} ${response.body}');
    }
    

    In your example you aren't encoding the JSON correctly.

    And here is another example of signing in. The class is a view model architecture that I talk about here.

    import 'dart:convert';
    
    import 'package:flutter/foundation.dart';
    import 'package:http/http.dart' as http;
    
    class LoginViewModel extends ChangeNotifier {
    
      String _token = '';
      bool _isLoggedIn = false;
      bool get isLoggedIn => _isLoggedIn;
      String get token => _token;
    
      Future onLoginPressed(String username, String password) async {
        if (username.isEmpty || password.isEmpty) {
          return;
        }
        _isLoggedIn = await _login(username, password);
        notifyListeners();
      }
    
      Future<bool> _login(String username, String password) async {
        var clientID = 'com.example.app';
        var clientSecret = '';
        var body = 'username=$username&password=$password&grant_type=password';
        var clientCredentials = Base64Encoder().convert('$clientID:$clientSecret'.codeUnits);
    
        Map<String, String> headers = {
          'Content-type': 'application/x-www-form-urlencoded',
          'authorization': 'Basic $clientCredentials'
        };
        var response = await http.post(YOUR_URL_HERE, headers: headers, body: body);
        final responseBody = response.body;
        if (response.statusCode != 200) {
          return false;
        }
    
        final map = json.decode(responseBody);
        _token = map['access_token'];
        return true;
      }
    }