The getter 'length' was called on null when called on Map object - dart

I forgot to call json.encode on my Map object before sending post request.
Wrong code:
var response = await http.post(url, body: data, headers: {"Accept": "application/json"});
Right code:
var response = await http.post(url, body: json.encode(data), headers: {"Accept": "application/json"});
On wrong code I got unexpected error:
The getter 'length' was called on null.
I am trying understand why? data is Map and it's not null.

Related

Getting Error: XMLHttpRequest error when using dart

I have tried POST request from dart code to django rest api on local machine.
the API works when I do POST from Postman but fails when using dart.
Can someone please explain why !
my dart code :
void post_call() async {
var headers = {
'Content-Type': 'application/json',
};
var data = {"_selectedValue":"yes","_DescriptionValue":"yes","_namefieldValue":"yes","_contactValue":"yes","_emailValue" : "yes"};
var url = Uri.parse('http://127.0.0.1:8000/first_app/forms/');
var res = await http.post(url, headers: headers, body: json.encode(data));
if (res.statusCode != 200) throw Exception('http.post error: statusCode= ${res.statusCode}');
print(res);
}
the API works when I do POST from Postman but fails when using dart.

http headers are not mutable in flutter

I am using this code to send http request using Dart:
var request = await httpClient.postUrl(Uri.parse(url));
Map jsonMap = {'pageSize': 10};
request.add(utf8.encode(json.encode(jsonMap)));
request.headers.set('content-type', 'application/json');
var response = await request.close();
if (response.statusCode == HttpStatus.OK) {
}
but it shows:
HttpException: HTTP headers are not mutable
why give me this tips and what should I do fix this?
You need to check HttpHeaders class page. (https://api.dart.dev/stable/2.10.5/dart-io/HttpHeaders-class.html)
HttpRequest and HttpClientResponse always have immutable headers.
HttpResponse and HttpClientRequest have immutable headers from the moment the body is written to.
request.add(utf8.encode(json.encode(jsonMap)));
This line is add Request Body so made HttpClientRequest header to immutable. So if you want to add headers, you need to do it before this line.
var request = await httpClient.postUrl(Uri.parse(url));
Map jsonMap = {'pageSize': 10};
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(jsonMap)));
var response = await request.close();
if (response.statusCode == HttpStatus.OK) {
}

How to Http Post with Json Body on Flutter

I am trying to get data from API. I need to pass value from the body, in postman without a header: application/JSON data is not displayed.
final response = await http.post(
"http://192.168.10.25:8080/Login/validateusername",
body: {"username": "user#PYA"},
headers: {'Content-Type': 'application/json'},
);
Error Message:
E/flutter (28851): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:
E/flutter (28851): Bad state: Cannot set the body fields of a Request with content-type "application/json".
Add the content type application/json
Future<String> apiRequest(String url, Map jsonMap) async {
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(jsonMap)));
HttpClientResponse response = await request.close();
// todo - you should check the response.statusCode
String reply = await response.transform(utf8.decoder).join();
httpClient.close();
return reply;
}
Simply encode body to json object when using content-type "application/json"
http.Response response = await http.post( uri , headers: headers, body: JsonEncoder().convert(body));
Another simple way is as bellow
import 'package:http/http.dart' as http;
String body = json.encode({
'foo': 'bar',
'complex_foo' : {
'name' : 'test'
}
});
http.Response response = await http.post(
url: 'https://example.com',
headers: {"Content-Type": "application/json"},
body: body,
);
use the http dart package
var data = {username:"username",password:"password"};
http.Response response = await http.post(
"yourApiroute",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: {"username": data.phone, "password": data.password});
var json = jsonCodec.encode(data);
print("json=$json");
var url = "http:yourAPIrouter.com/etc";
var response = await http.post(
url,
headers:{ "Accept": "application/json" } ,
body: { "json": '$json'},
encoding: Encoding.getByName("utf-8")
);
and dont forget add the key "json" in postman
I am doing almost the same. However, I tried to avoid doing back-end, like in your case. I just did a minimal php request so that I would not waste or patience learning what is needed to develop a user management controller.
However, I faced several limitations and problems that Flutter alone can't solve. After some denial, I gave a try. Lumen, a light version of the Laravel Framework, some tutorials and some past experience, I eventually realized that the API should carry most of the authentication, and not the application itself. I digressed.
In my case, the code of the fuction to a http post is:
Future<Post> createPost() async {
final url = "http://localhost:8000/api/login";
Map<String, String> body = {
'user': user.text,
'pass': pass.text,
};
await http.post(url, body: body);
print(body);
return http.;
}
I first convert it into a map. I prefer this method over parsing json, because down the line, if I need to add more variables, I just make the map bigger.
I just have a question: What does your http://192.168.10.25:8080/Login/validateusername look like? I think that there is no need to specify the type of information that your body parses.

HTTP Post passing 2 parameters and content type key flutter

I am struggling with making a http post call returning JSON in flutter. I keep getting a 500 error and I dont know what the issue is. I need to pass a username and password in the header and I think the issue is how im doing it. Here is the code.
Future<User> LoginUser(String username, String password ) async {
final response =
await http.post('http://xx.xxx.xxx.xxx/api/Login',
headers: {"Content-Type": "application/json", 'email' : username , 'password' : password });
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
return User.fromJson(json.decode(response.body));
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load user');
}
}
It wont get past the 200 check because it is getting a 500. I cant find any examples with passing 2 parameters in the header and the content type so im not sure im doing that correctly.
If we have to pass 2 arguments like key and any other data, Then follow the code(Only for Post Request)
Future<ClassType> callApi()async{
const String url="your/request/to/post/link/url";
const Uri=Uri.parse(url);
Map passValues={'token':'yOuRtOkEnkEy','user_id':'123456789'};
var body = json.encode(token);
var response;
try {
response = **await** http.post(
uri,
headers: {'Content-Type': 'application/json'},
body: body,
);
} catch (e) {
print(e);
}
if (response.statusCode == 200) {
var jsonString = response.body;
var jsonMap = json.decode(jsonString);
print(jsonMap);
} else {
print('API FAILED');
}
return response;
}

Can't create account in aqueduct's db_and_auth/wildfire example

I have been trying to learn how to use Aqueduct's authorization but I am struggling with some errors.
I found this question (OAuth Error using Aqueduct, mismatched ManagedPropertyType), which solved the first error saying it was expecting a string while an _ImmutableList was being passed. Nevertheless, whenever I make a the following POST request:
Future main() async {
var http2 = new http.Client();
var clientID = "com.wildfire.mobile";
var clientSecret = "myspecialsecret ";
var body = "username=usr&password=pwd&grant_type=password";
var clientCredentials = new Base64Encoder().convert(
"$clientID:$clientSecret".codeUnits);
var response = await
http.post(
"http://localhost:8081/register",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Basic $clientCredentials"
},
body: body);
I get a 500 error as a response and the following exception:
NoSuchMethodError: The getter 'credentials' was called on null.
in
request.authorization.credentials.username
Nevertheless, in the _user table I see an entry for the user I registered. Should I juts ignore the error or is there someway to solve this issue?
Edit:
It was indeed a misconfiguration issue. After deleting all my databases, I added a database.yaml file, which I thought was the same as the config.yaml but apparently is not.
Credentials will be null if the request doesn't pass through an Authorizer. In this case, you'll want a basic authorizer:
router
.route("/register")
.pipe(new Authorizer.basic(authServer))
.generate(() => new RegisterController());

Resources