Unexpected character (at character 2) while parsing json using dio - flutter

I was getting data from api using dio. It was successful but when data gets and it gets an exception.
Unexpected character (at character 2) {data:{id:5, name: ....
in error log, shows an arrow in beneath d(data)
What to do?

When I changed responsetype only for this API. It worked.
await dio.get(
url,
options: Options(
responseType: ResponseType.plain,
),

This is not related to Dio however, I had this error when accessing data from the local repository (Shared Preferences).
After hours I discovered that the data was not correctly saved as a json string which made the decoding throw an error.
Correct way.
await _prefs?.setStringList(
_itemsKey, itemsJson.map((e) => json.encode(e)).toList());

Related

Is anyone knows how Flutter URI encoding/decoding works?

Is anyone knows how Flutter URI encoding/decoding works?
I have one issue. Let me give you some background on the issue. We have one deep link which will give us the email and access token code to reset the password. We will validate the token on the front end and then allow users to do a reset.
Here is the sample URL from Firebase dynamic link
https://example.com/auth/resetPassword/?access_token=abcd&email=test+abc#xyz.com
Firebase dynamic link will give us this URL in the URI object. The issue is when I try to fetch the query params from this URI object, it removes plus sign from an email and replaces it with the space character instead. E-mail should same as displayed in the above link. This is the email received when I fetch query params: test abc#xyz.com
I have created two dart pads to figure out the issue. Here is the 1st sample where I am parsing (since firebase dynamic link is doing the same) the URL into the URI object and tried printing the output. As expected it removes the plus sign.
Code:
main() {
var httpsUri = Uri.parse("https://example.com/auth/resetPassword/?access_token=abcd&email=test+abc#xyz.com");
print(httpsUri.queryParameters);
}
Output:
{access_token: abcd, email: test abc#xyz.com}
In another sample, I tried creating the URI object from the same parameters and link but manually. Here is the code
Code:
main() {
var httpsUri = Uri(
scheme: 'https',
host: 'example.com',
path: '/auth/resetPassword/',
queryParameters: {
'access_token': 'abcd',
'email': 'test+abc#xyz.com'
});
print(httpsUri.queryParameters);
}
Output:
{access_token: abcd, email: test+abc#xyz.com}
If you see here, the email is correctly displayed.
My exact scenario is matching with the first sample code. Based on my findings it removes the plus sign due to encoding and decoding of the URL as a plus sign has a special meaning in the URL. But on the other hand why it is not happening in 2nd example?
Any help would be appreciated!
+ is a reserved character for URIs and therefore should be encoded to %2B if you want a literal + character.
But on the other hand why it is not happening in 2nd example?
Your second example works because it constructs a Uri object directly, and if you were to convert it to a String, it would perform necessary encodings for you. That is, print(httpsUri) would output:
https://example.com/auth/resetPassword/?access_token=abcd&email=test%2Babc%40xyz.com
rather than original (malformed) URL:
https://example.com/auth/resetPassword/?access_token=abcd&email=test+abc#xyz.com

Post request flutter

i'm trying to do a post request but all the time i get this error
Uncaught Error: XMLHttpRequest error.
i' working on dartpad on line and i'm using the package http.dart .I don't get the problem despite i post a json format i dont understand why the error is with the xml ?!
this my code :
import 'package:http/http.dart' as http;
void main() async {
// This will be sent as form data in the post requst
var map = new Map<String, dynamic>();
map['username'] = '**********';
map['password'] = '**********';
final response = await http.post(
Uri.parse('************'),
body: map,
);
print(response.body);
}
I suggest the following:
Verify that your URI is correct, I tried your code on DartPad with a simple GET request onto a Free API I found on the web and I get no errors
Verify that your endpoint has no weird CORS errors with another client (e.g. postman or Dio, see below)
Verify that you don't have weird cache values onto your machine. Doing a flutter clean && flutter pub get might help
Consider using Dio (pub.dev) as your http client as the dart's inner http package isn't quite ready for production imho.

Google Books API not returning the same as displayed on browser (Flutter)

I am building a book app with Flutter for Android and iOS. I am using Google Books API to retrieve book data, but I have noticed something strange which I dont understand. If we look at the book data displayed in chrome browser (https://www.googleapis.com/books/v1/volumes/b3GuDwAAQBAJ), we can see that the content (eg. field categories) is different than what I get when calling http response and printing out it's body. In addition to that, it also seems like unicode characters (eg. from description) are not sent.
The code that I'm using to get the API data can be seen below:
Response result = await http.get(Uri.parse(url), headers: {'content-type': 'application/json; charset=utf-8'});
if (result.statusCode == 200) {
final jsonResponse = jsonDecode(utf8.decode(result.bodyBytes));
if (jsonResponse["totalItems"] == 0) {
return List.empty();
}
//this prints out the content in above image
print(result.body.toString());
final booksMap = jsonResponse['items'];
List<dynamic> books = booksMap.map((i) => Book.fromJson(i)).toList();
return books;
It seems that https://www.googleapis.com/books/v1/volumes/b3GuDwAAQBAJ gives different data than your usual search query (eg. https://www.googleapis.com/books/v1/volumes?q=isbn:9780143123231). I do not know the reason why.
You can see the API response in raw form due to which unicode are present
Raw Form image from browser
but when you get api response you can parse into json, By parsing json that unicodes are removed and data is in proper format
if you use json Formatter extension in chrome you can see that the data in chrome in Json form and the response from api when you are hitting api by code are same.
Data in Json Form in Browser
in the application code , you set headers: {'content-type': 'application/json; thats why u received Json data code. and its not problem because you will use this data into your application,
you can see more content types here
Blockquote

URL interpolation using Uri class

I'm having an issue with the Uri class, the code below used to work before the updates but now, the issue is that it uses a String instead of a Uri URL, I've been trying to update this interpolation to the newest standard with no success. This URL is simply getting data from Firebase with tokens from users that are signed in.
final response = await http.get("$_url.json?auth=$_token");
I already managed parse the main part of the url:
Uri _url = Uri.parse("https://my-project.firebaseio.com/example");
The final result used to be something like this:
https://my-project.firebaseio.com/example.json?auth=xLwOQ2GEQxPp0h0QD1foHgSyXR52
How do I interpolate this URL properly since I have one value that isn't static? (_token)
You should use the Uri.https constructor to create the Uri you then use with get.
For example
var uri = Uri.https('my-project.firebaseio.com', '/example', queryParameters: {'auth': _token})
See Uri.http documentation

Axios's response, what's in it??.....const response = await axios

I'm using Axios in WP e.g.
const response = await axios.delete(universityData.siteURL + "/wp-json/wp/v2/note/" + thisNote.getAttribute("data-noteID"))
All works fine but what I don't understand is the structure / content of 'response'. How do I interrogate 'response'? I had assumed for instance if I did console.log('Axios response: ' + response.data) I'd get a nicely laid out JSON like OO output in the Chrome console panel. But all I see is: Axios response: [object Object]
I can do this response.data.userNoteCount and I get something sensible back. BTW 'userNoteCount' is a field I added to my JSON for my custom post type. But how else do I see all the content of response without specifically having to target it?
Thanks to another contributor elsewhere this is the answer:
When you do the console.log you're adding the JSON object to the
string of Axios Response, so the JSON object is being converted to a
string, hence the object Object.
If you do it as two seperate lines, like
console.log('Axios Response');
console.log(response.data);
Then it will be outputted as the actual object.
With it being an HTTP Request though, rather than outputting it into
the console, what I'd do is open the Network tab of the browser
development tools, and select the XHR tab, and then the request will
appear in there and you can inspect the full response body there
without having to log it.