How to Call Get request by passing Object as query parameter using Dio in flutter - flutter

How to pass Filter Json Object as query parameter in Dio GET request call for this API in flutter.
I am using below code for passing query parameter but it is not working properly
Future<GetPropertyListResponseModel> getPropertyList(
GetPropertyListRequestModel queryParam) {
final params = <String, dynamic>{
'Filters': {"offset":0,"limit":50,"UnparsedAddress":"t"},
};
var dioCall = dioClient.get(ApiConstants.GET_PROPERTY_LIST, queryParameters:params);
try {
return callApiWithErrorParser(dioCall)
.then((response) => GetPropertyListResponseModel.fromJson(response.data));
} catch (e) {
rethrow;
}
In Order to get success response the GET URL should be like below
https://cribzzz-api.apps.openxcell.dev/property?Filters=%7B%22offset%22%3A0%2C%22limit%22%3A50%2C%22UnparsedAddress%22%3A%22t%22%7D
But when I use the above code the URL becomes as below
https://cribzzz-api.apps.openxcell.dev/property?Filters%5Boffset%5D=0&Filters%5Blimit%5D=50&Filters%5BUnparsedAddress%5D=t

Related

How to make a POST request with httpclient in net core and javascript

Im having a very bad time triying to figure out this problem, I have a web API made in net core 6 with Entity Framework, in this web api I have to consume a third party API. If a try to make a POST request directly the Swagger UI it works perfectly:
POST in Swagger
HOWEVER, if i made a post request in javascript using fetch it return a 400 error, that to be honest doesn't say much:
400 error response
I know there is no missing data in my post request, I checked a lot, in fact there is no field call "data".
Here is the code to make a fetch in the frontend:
return fetch(apiURL, {
method: 'POST',
headers: {
'Content-Type': 'text/plain',
},
body: JSON.stringify(data)
})
.then(response => response.json())
Here is the post method in net core
[HttpPost]
public async Task<string> PostProductAsync(string data)
{
HttpResponseMessage response = await _client.PostAsync(path, new StringContent(data, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
return json;
}
I'm a bit confused. What could i be doing wrong.
UPDATE
I followed each instruction in the answers section, and I can say that it makes a lot of sense to put [FromBody] in the POST method since in the fetch method I am sending the data in the body.
However this led me to a new parsing error: parsing error after POST request
I have been searching in other forums about this error, it seems that what is recommended in this case is to make a class Unexpected character encountered while parsing value: . Path '', line 1, position 1
Now, the problem that i have with this approach its that i have quite a big json to post, witch means that i will have to create a lot of classes to make this possible. Its there any way to this without creating a class?
So far i tried the following changes in the POST method:
Adding [FromBody]
[HttpPost]
public async Task<string> PostProductAsync([FromBody] string data)
{
HttpResponseMessage response = await _client.PostAsync(path, new StringContent(data, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
return json;
}
This one leads to the parsing error mentioned before.
Adding [FromBody] and changing string to object
[HttpPost]
public async Task<string> PostProductAsync([FromBody] object data)
{
HttpResponseMessage response = await _client.PostAsync(path, new StringContent(data.ToString(), Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
return json;
}
This one leads to a non valid JSON is not a valid JSON error
Your Swagger UI is sending your data as a Query parameter, but you are trying to post it through body in your fetch. They are two different methods of post. I recommend you use body only.
Change your controller method to use the [FromBody] parameter attribute:
PostProductAsync([FromBody] string data)
More information from https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api#using-frombody
Defaults for a string, in your case:
If the parameter is a "simple" type, Web API tries to get the value from the URI. Simple types include the .NET primitive types (int, bool, double, and so forth), plus TimeSpan, DateTime, Guid, decimal, and string, plus any type with a type converter that can convert from a string. (More about type converters later.)
So the default behavior is what Swagger is currently using.
Since you want to pass json type data,you need to use 'Content-Type': 'application/json' in fetch,and then use [FromBody]in action.
fetch:
return fetch(apiURL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
})
.then(response => response.json())
action:
[HttpPost]
public async Task<string> PostProductAsync([FromBody]string data)
{
HttpResponseMessage response = await _client.PostAsync(path, new StringContent(data, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
return json;
}
In your case, you can bind model in two ways.
Simple type model binding approach
Since you are accepting simple type string value in controller, you can use 'Content-Type': 'application/x-www-form-urlencoded' in fetch and you can pass parameter data in the URL as following:
At fetch:
let apiURL = `https://localhos:8080/Test/data`;
return fetch(apiURL, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: null
}).then(response => response.json())
Complex type model binding approach
Let's assume you're now posting complex object type data. To post data from request body Content-Type should be application/json. And add [FromBody] in the action to define the location to get data from request. Here's the example code snippet.
At fetch:
return fetch(apiURL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
}).then(response => response.json())
At controller:
[HttpPost]
public async Task<string> PostProductAsync([FromBody]string data)
{
HttpResponseMessage response = await _client.PostAsync(path, new StringContent(data, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
return json;
}
On a side note, please avoid using text/plain as Content-Type to avoid security issues.
Hope this helps you and here's for your further reference for model binding in ASP.NET Core.

How to get named json response Flutter using http get method

ok here is my json format
{
"success":true,
"user":{
"name":"example"
"email:"example#email.com"
}
}
ok by using Chopper Flutter it was easy just to get the user object by calling
response.body["user"]
however the current Chopper version ie the null safety is not stable...so how do you call this method in HTTP? to get the user object only...
Response response = await http.get(Uri.parse('enterYourUrlHere');
Map<String, dynamic> body = jsonDecode(response.body);
var user = body['user'];
print(user['email']); // prints out example#email.com"

How to use List data returned from an API call

Im attempting to get back a list of data from an API call and send this list of data to a local sqlite database I've created for it. I'm getting an issue with the data being a type <List> and I'm not sure how to convert it to something usable. I'm just trying to assign that data from the api call to a variable so I can just simply send it to the sqlite database. Any advice is welcome! Thanks!
This is the code where I'm attempting to get that data from the API call and send it to the sqlite database.
if(user.success) {
Quarter quarters;
quarters = await getQuarters();
QuarterDBProvider.quarterDB.newQuarter(quarters);
}
This is where the API call is performed
Map data;
List<Quarter> quarterFromJson(String str) =>
List<Quarter>.from(json.decode(str).map((x) => Quarter.fromJson(x)));
Future<List<Quarter>> getQuarters() async {
final http.Response response = await http.get(
'https://myfakeapi/quarters',
);
if (response.statusCode < 400) {
return quarterFromJson(response.body);
} else {
throw Exception('Failed to get quarters');
}
}
the response from api is list and it is not String.
List<Quarter> _listQuarter= [];
var json = jsonDecode(response.body) as List<dynamic>;
json.forEach((element) {
_listQuarter.add( -do all your workaround- );
});
return _listQuarter;

How display data which comes from async function?

I use api for get information which need to be display
Future <String> Get_Amount_Jackpot() async {
// SERVER LOGIN API URL
var url2 = 'https://www.easytrafic.fr/game_app/get_jackpot_lotto.php';
// Starting Web API Call.
var response2 = await http.get(url2,headers: {'content-type': 'application/json','accept': 'application/json','authorization': globals.token});
// Getting Server response into variable.
Map<String, dynamic> jsondata2 = json.decode(response2.body);
return jsondata2["value"];
}
I call it here :
void initState() {
ListLotto = Grille_display();
jackpot = Get_Amount_Jackpot();
super.initState();;
}
How i can display the value "jackpot" which is a simple number on mobile screen. Note i use futurebuilder for another api request, this is why it is complicated. Normally i use futurebuilder for display async data but there i need 2 différents api request so 2 futureBuilder ??? Is it possible and how do that ?
You can use then to get the returned value from the function.
Get_Amount_Jackpot().then((value){
//value is what is returned from the function
jackpot = value;
});
I'm not sure if you can use uppercase letter as the start of a function name, but i copied your function name for my answer. Hope this helps.

RedirectException: Redirect loop detected

I'm testing a request to get data from an URL using dio in my Dart code.
import 'package:dio/dio.dart';
class Api {
Dio dio = Dio();
var path = 'https://jsonplaceholder.typicode.com/users';
void getHttp() async {
try {
Response response = await dio.get(path);
print(response.data);
} catch (e) {
print(e);
}
}
}
In this case it brings the result correctly.
But, I actually need get data from this URL:
http://loterias.caixa.gov.br/wps/portal/loterias/landing/megasena/!ut/p/a1/04_Sj9CPykssy0xPLMnMz0vMAfGjzOLNDH0MPAzcDbwMPI0sDBxNXAOMwrzCjA0sjIEKIoEKnN0dPUzMfQwMDEwsjAw8XZw8XMwtfQ0MPM2I02-AAzgaENIfrh-FqsQ9wNnUwNHfxcnSwBgIDUyhCvA5EawAjxsKckMjDDI9FQE-F4ca/dl5/d5/L2dBISEvZ0FBIS9nQSEh/pw/Z7_HGK818G0KO6H80AU71KG7J0072/res/id=buscaResultado/c=cacheLevelPage/=/?timestampAjax=1588600763910
Using Postman I can access the data:
So, the problem is that, if I try to get data from that URL in my code, I get the following exception error:
I/flutter (23393): DioError [DioErrorType.DEFAULT]: RedirectException: Redirect loop detected
If this URL is redirecting, why is it working when using Postman? Anyway, how could I handle this redirected request in order to access data?
After a while, I noticed that the response to this request is coming as HTML and not as Json. So I needed to create a way to get DOM coming from the request, removing HTML tags and encoding string to Json.