http Post issues

426 views
Skip to first unread message

Kevin Roberson

unread,
Mar 12, 2021, 11:33:15 PM3/12/21
to Flutter Development (flutter-dev)
Hello,

I'm having trouble retrieving data via http.  I want to send a user name to my node.js api and have it return the encrypted password from the database.   I must be missing a step somewhere.  In the same app, I have a registration form that posts to the same database using the same api that works fine.  And even this password request works fine in Postman, returning this in the body:  [{"password":"8V3h7rWLf9BZv5J2sAZwpQ=="}]

In debug, I find my storedPW var is empty and get this error when hovering over the headers property of the http post:
<error>:<getObject: NoSuchMethodError: The getter 'uri' was called on null.>

This probably tells me the issue, but I'm not experienced enough to understand it.

Thanks for any help, insight, pointers you can provide to help me learn.

Kevin

node.js route:
app.post('/getPW', (reqres) => {
  var query = sql.USERS_GET_PW;
  query = query.replace("@username", "'" + req.query.username + "'");
  pool.query(query, function (errresult) {
    if (err) {
      res.status(503).send(result);
    } else {
      res.status(200).send(JSON.stringify(result));
    }
  });
});

Flutter code:
TextButton(
                          onPressed: () {
                            //if (_loginFormKey.currentState.validate()) {
                            Future storedPW = getPW(_userIDTextController.text);
                            storedPW.then((data) {
                              storedPWStr = data[0]['password'];
                              print(storedPWStr);
                            }, onError: (e) {
                              print(e);
                            });

                            final typedPW = encr(_passwordTextController.text);

                            if (typedPW == storedPWStr) {
                              showConfirmDialog(context);
                            }
                            //}
                          },
                          child: Text(
                            'Login',
                            style: GoogleFonts.roboto(
                                fontStyle: FontStyle.normal,
                                fontSize: 18.0,
                                fontWeight: FontWeight.w400,
                                height: 2.0,
                                color: Colors.blue,
                                decoration: TextDecoration.underline),
                          ),
                        ),

Future getPW(userId) async {
    final response = await http.post(
      Constants.API_URL + '/getPW?username=' + userId,
      headers: <StringString>{'Content-Type': 'application/json'},
    );
    print('$response.statusCode');
    if (response.statusCode != 200) {
      String error =
          'Error signing in - $userId.  Response code: ${response.statusCode.toString()}';
      print('Error: $error');
    }
  }

Suzuki Tomohiro

unread,
Mar 12, 2021, 11:49:37 PM3/12/21
to Kevin Roberson, Flutter Development (flutter-dev)
Share the stack trace of the error. I’ll tell you which line you have to look at. (spoiler: it’s around the top of the stack trace)

--
You received this message because you are subscribed to the Google Groups "Flutter Development (flutter-dev)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flutter-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/flutter-dev/fa4d3c09-19b8-49e0-ae6b-3e0a7665bf28n%40googlegroups.com.

Kevin Roberson

unread,
Mar 13, 2021, 12:37:02 AM3/13/21
to Flutter Development (flutter-dev)
Thanks for the reply Suzuki.  Here is the stack trace.  I see the error at the top, but I don't understand why the method is null/empty:

Launching lib\main.dart on Chrome in debug mode...
Debug service listening on ws://127.0.0.1:59390/h2-_n7PSViQ=/ws
Running with unsound null safety
Connecting to VM Service at ws://127.0.0.1:59390/h2-_n7PSViQ=/ws
Error: NoSuchMethodError: '[]'
Dynamic call of null.
Receiver: null
Arguments: [0]
    at Object.throw_ [as throw] (http://localhost:59335/dart_sdk.js:5334:11)
    at Object.defaultNoSuchMethod (http://localhost:59335/dart_sdk.js:5779:15)
    at Object.noSuchMethod (http://localhost:59335/dart_sdk.js:5774:27)
    at Object._checkAndCall (http://localhost:59335/dart_sdk.js:5509:27)
    at Object.callMethod (http://localhost:59335/dart_sdk.js:5587:17)
    at _RootZone.runUnary (http://localhost:59335/dart_sdk.js:38889:58)
    at _FutureListener.then.handleValue (http://localhost:59335/dart_sdk.js:33875:29)
    at handleValueCallback (http://localhost:59335/dart_sdk.js:34435:49)
    at Function._propagateToListeners (http://localhost:59335/dart_sdk.js:34473:17)
    at _Future.new.[_completeWithValue] (http://localhost:59335/dart_sdk.js:34315:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:59335/dart_sdk.js:34338:35)
    at Object._microtaskLoop (http://localhost:59335/dart_sdk.js:39176:13)
    at _startMicrotaskLoop (http://localhost:59335/dart_sdk.js:39182:13)

Sawyer Cutler

unread,
Mar 13, 2021, 1:36:54 AM3/13/21
to Suzuki Tomohiro, Kevin Roberson, Flutter Development (flutter-dev)
Wrap the body with jsonEncode and set your content type to application json and it should fix the errors. 




On Mar 12, 2021, at 10:49 PM, Suzuki Tomohiro <suz...@gmail.com> wrote:



Kevin Roberson

unread,
Mar 13, 2021, 3:18:45 PM3/13/21
to Flutter Development (flutter-dev)
Suzuki:  Yes it is Web and you are correct, the data var is null.
Sawyer:  I'm not sending a body, but the body being returned is using json.stringify in the node.js api.  The Content-Type is also already set to application/json in Flutter.

Both:  This is the response that shows in the api, just before it returns:
 [ RowDataPacket { password: '8V3h7rWLf9BZv5J2sAZwpQ==' } ]

What type/format of var do I need to convert it into from the Future Response that is returned?  Do I have all of these correct below?  The ultimate goal is this statement:  if (typedPW == storedPWStr)....

Future storedPW = getPW(_userIDTextController.text);
                            storedPW.then((data) {
                              storedPWStr = data["password"];     <== This was previously:  data[0]['password']
                            }, onError: (e) {
                              print(e);
                            });
Future getPW(userId) async {
    final response = await http.post(
      Constants.API_URL + '/getPW?username=' + userId,
      headers: <StringString>{'Content-Type': 'application/json'},
      body: '',
    );

Thanks to both of you for your help!
Kevin

Suzuki Tomohiro

unread,
Mar 13, 2021, 6:45:05 PM3/13/21
to Kevin Roberson, Flutter Development (flutter-dev)
What is he value of the variable “response” in getPW?

Kevin Roberson

unread,
Mar 13, 2021, 10:09:13 PM3/13/21
to Flutter Development (flutter-dev)
The value of "response" in getPW is:
bodyBytes:NativeUint8List ([91, 123, 34, 112, 97, 115, 115, 119, 111, 114, 100, 34, 58, 34, 56, 86, 51, 104, 55, 114, 87, 76, 102, 57, 66, 90, 118, 53, 74, 50, 115, 65, 90, 119, 112, 81, 61, 61, 34, 125, 93])
<error>:<getObject: NoSuchMethodError: The getter 'uri' was called on null.>

Suzuki Tomohiro

unread,
Mar 13, 2021, 10:22:27 PM3/13/21
to Kevin Roberson, Flutter Development (flutter-dev)
Nice. Then you need to investigate why the value in response does not go to "data" variable.

- Declare the type for getPW method with type parameter, rather than just "Future". "Future" of what?
- Also declare the type for "data" variable.


Kevin Roberson

unread,
Mar 14, 2021, 12:29:37 AM3/14/21
to Flutter Development (flutter-dev)
That makes total sense.  But where I'm confused is, the async http request returns a Future<http.Response>.  I couldn't find a way to change it to a string, other than changing it to a Future<Dynamic> and using .then.  Do I need to map it somehow to a Response data structure/object and get the payload from that?  I've tried several examples I've found online, but none are as simple as returning a single string.  Thanks for your help and patience Suzuki.

Suzuki Tomohiro

unread,
Mar 14, 2021, 1:58:57 AM3/14/21
to Kevin Roberson, Flutter Development (flutter-dev)
Declare it as Future<http.Response>. Can you share the URL of the documentation of the Response class?


> Do I need to map it somehow to a Response data structure/object and get the payload from that?  

Yes, you need to do that.


Kevin Roberson

unread,
Mar 14, 2021, 1:01:11 PM3/14/21
to Flutter Development (flutter-dev)
https://pub.dev/documentation/http/latest/http/Response-class.html

Okay, I've tried this, but still get the same error:
<error>:<getObject: NoSuchMethodError: The getter 'uri' was called on null.>

Future<Password> storedPW =
                                  getPW(_userIDTextController.text);
                              storedPW.then((encPW) {
                                storedPWStr = encPW.password;
                              }, onError: (e) {
                                print(e);
                              });

Future<Password> getPW(String userId) async {
    final response = await http.post(
      Constants.API_URL + '/getPW?username=' + userId,
      headers: <StringString>{'Content-Type': 'application/json'},
    );

    if (response.statusCode != 200) {
      String error =
          'Error signing in - $userId.  Response code: ${response.statusCode.toString()}';
      print('Error: $error');
    }

    return Password.fromJson(jsonDecode(response.body));
  }

class Password {
  final String password;

  Password({this.password});

  factory Password.fromJson(Map<StringString> json) {
    return Password(
      password: json['password'],
    );
  }
}

Suzuki Tomohiro

unread,
Mar 14, 2021, 1:10:59 PM3/14/21
to Kevin Roberson, Flutter Development (flutter-dev)
Nice. Yes the document says body is what you were looking for and I see that you now use the field.

Can you add type to encPW variable? Do you see the variable having expected (non-null) value? Or the exception is happening before that?

Kevin Roberson

unread,
Mar 14, 2021, 3:00:17 PM3/14/21
to Flutter Development (flutter-dev)
I do have the type declared.  I didn't include that part, but I have this declared globally for now, until I get this working.
 String storedPWStr = '';
  Password encPW;

It looks to me like the exception is happening during the post itself:
Future<Password> getPW(String userId) async {
    http.Response response = await http.post(
      Constants.API_URL + '/getPW?username=' + userId,
      headers: <StringString>{'Content-Type': 'application/json'},
    );

This post (that writes a registration record, but I'm not using the return value, because I ran into this same issue) works fine:
final response = await http.post(
      Constants.API_URL + '/addUser',
      headers: <StringString>{'Content-Type': 'application/json'},
      body: json.encode(regForm),
    );

The api server is getting this request (console.log of result that is returned):
Server monnieapi running at port 5000...
[ RowDataPacket { password: '8V3h7rWLf9BZv5J2sAZwpQ==' } ]

Suzuki Tomohiro

unread,
Mar 14, 2021, 3:16:45 PM3/14/21
to Kevin Roberson, Flutter Development (flutter-dev)
I don’t develop Flutter web but can you try to add breakpoints to see something was null when the exception occurs?

Looking at the two method calls, I see the former (problematic one) does not have a body. Is that causing the problem?

(probably not the cause of the problem) Please declare encPW’s type in the lambda argument (Declaring it as a global variable does not have any effect):

storedPW.then((Password encPW) {

Kevin Roberson

unread,
Mar 14, 2021, 9:04:55 PM3/14/21
to Flutter Development (flutter-dev)
Okay, I've tried it now with a body and changing the declaration as you suggested.  I've even added encoding (it defaults to UTF8 anyway) and watched it step through everything, but I don't see where the error is occurring.  It seems to come up as soon as the post executes.  I really appreciate all of your help with this.  I think I'm going to have to find an alternate solution.  I just can't imagine why this is not working.  I've done this before in JS without any issues.  It's really odd.  Flutter Web is still in beta so maybe there are issues there?  Thanks again for your help Suzuki.  I really appreciate how you led me through the process so I could learn as we tried different things.  I'm sure I'll be posting more questions soon.  Take care!
Reply all
Reply to author
Forward
0 new messages