Flutter - Unexpected character when decoding json - json

Unexpected characters  showing up when I decoding json
E/flutter (27537): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: FormatException: Unexpected character (at character 1)
E/flutter (27537): {"data":[{"kode_wilayah":"056001 ","nama":"Kec. Karang Pilang","mst_kod...
E/flutter (27537): ^
E/flutter (27537):
E/flutter (27537): #0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1392:5)
Here is the code
Future<List<Kecamatan>> getData() async {
List<Kecamatan> list;
String link =
"http://jendela.data.kemdikbud.go.id/api/index.php/CWilayah/wilayahGET/?mst_kode_wilayah=056000";
var res = await http
.get(Uri.encodeFull(link), headers: {"Accept": "application/json;charset=UTF-8", "Charset": "utf-8"});
print(res.body);
if (res.statusCode == 200) {
var data = json.decode(res.body);
var rest = data["data"] as List;
print(rest);
list = rest.map<Kecamatan>((json) => Kecamatan.fromJson(json)).toList();
}
print("List Size: ${list.length}");
return list;
}
//inside build function
final kec = FutureBuilder<List<Kecamatan>>(
future: getData(),
builder: (BuildContext context,
AsyncSnapshot<List<Kecamatan>> snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
return DropdownButton<Kecamatan>(
items: snapshot.data
.map((camat) => DropdownMenuItem<Kecamatan>(
child: Text(camat.nama),
value: camat,
))
.toList(),
onChanged: (Kecamatan value) {
setState(() {
_selectedKec = value;
});
},
isExpanded: false,
//value: _currentCamat,
hint: Text('Pilih Kecamatan'),
);
});
Anybody know how to remove those characters? or maybe you can show me another method to create dropdown menu based on json?

You can do this in such a way:
if (res.statusCode == 200) {
// <============
final prefix = '';
var body = res.body;
if (body.startsWith(prefix)) {
body = body.substring(prefix.length);
}
// ============>
var data = json.decode(body);
var rest = data["data"] as List;
}

Related

Unhandled Exception: FormatException: Unexpected character (at character 1) Flutter connecting mysql

I am getting this error in flutter when I am making my login page, I am sure that the server is returning JSON not HTML but I am still getting the error. I have even tried using some "test" links and I am getting the same error.
E/flutter (25538): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: FormatException: Unexpected character (at character 1)
E/flutter (25538): <br />
E/flutter (25538): ^
E/flutter (25538):
This is my code
Future userLogin() async {
setState(() {
visible = true;
});
String email = emailController.text;
String password = passwordController.text;
var url = 'http://192.168.1.2/***************/*********.php';
var data = {'email': email, 'password': password};
var response = await http.post(Uri.parse(url), body: json.encode(data));
var message = jsonDecode(response.body);
if (message == 'Login Matched') {
// Hiding the CircularProgressIndicator.
setState(() {
visible = false;
});
Navigator.push(
context, MaterialPageRoute(builder: (context) => StageOne()));
} else {
setState(() {
visible = false;
});
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(message),
actions: <Widget>[
FlatButton(
child: new Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}

_TypeError (type 'String' is not a subtype of type 'Map<dynamic, dynamic>')

i'm trying to create an auth user register with laravel. Then I got this kind of problem with my json. I created a dynamic map call to set the received json.
createAccount() async{
bool emailValid = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+"
).hasMatch(_email);
if(emailValid){
http.Response response = await AuthService.register(
_name, _email, _password
);
var encodeFirst = jsonEncode(response.body);
Map responseMap = jsonDecode(encodeFirst);
if(response.statusCode ==200){
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) => HomePage()));
} else{
errorSnackBar(context, responseMap.values.first[0]);
}
} else {
errorSnackBar(context, 'email not valied');
}
}

Writing an readin json file i have this error: Unhandled Exception: FormatException: Unexpected end of input (at character 1)

I am trying to dynamically create json file on device, the file is created successfully, but when I try to do the jsonDecode it throws this error.
The error is this:
════════ Exception caught by widgets library ═══════════════════════════════════
The following LateError was thrown building Home(dirty, state: HomeState#853db):
LateInitializationError: Field 'fileContent' has not been initialized.
The relevant error-causing widget was
Home
package:json_storage/main.dart:101
When the exception was thrown, this was the stack
#0 HomeState.fileContent (package:json_storage/main.dart)
package:json_storage/main.dart:1
#1 HomeState.build
package:json_storage/main.dart:183
#2 StatefulElement.build
package:flutter/…/widgets/framework.dart:4691
#3 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4574
#4 StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:4746
...
════════════════════════════════════════════════════════════════════════════════
I/flutter (23568): true
E/flutter (23568): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: FormatException: Unexpected end of input (at character 1)
E/flutter (23568):
E/flutter (23568): ^
E/flutter (23568):
E/flutter (23568): #0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1404:5)
E/flutter (23568): #1 _ChunkedJsonParser.close (dart:convert-patch/convert_patch.dart:522:7)
E/flutter (23568): #2 _parseJson (dart:convert-patch/convert_patch.dart:41:10)
E/flutter (23568): #3 JsonDecoder.convert (dart:convert/json.dart:506:36)
E/flutter (23568): #4 JsonCodec.decode (dart:convert/json.dart:157:41)
E/flutter (23568): #5 jsonDecode (dart:convert/json.dart:96:10)
E/flutter (23568): #6 HomeState.initState.<anonymous closure>
package:json_storage/main.dart:131
E/flutter (23568): #7 _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter (23568): #8 _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter (23568): <asynchronous suspension>
E/flutter (23568):
I have already tried putting it async just in case but it seems that it is not the problem, so I do not know what may be happening.
Here I leave the code, it is simply the main.dart file I do not have anything else since it is a test app to see if I could create that json and write in it, also I have used the path_provider package, but that's all, I can put a repository in github if necessary, but just copy and paste this code and add path_provider in pubspec.yaml.
import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(new MaterialApp(
home: new Home(),
));
}
class Home extends StatefulWidget {
#override
State createState() => new HomeState();
}
class HomeState extends State<Home> {
TextEditingController keyInputController = new TextEditingController();
TextEditingController valueInputController = new TextEditingController();
late File jsonFile;
late Directory dir;
String fileName = 'myJsonFile.json';
bool fileExists = false;
// Si usas otra cosa Pon String, dynamic
late Map<String, dynamic> fileContent;
#override
void initState() {
super.initState();
getApplicationDocumentsDirectory().then((Directory directory) {
dir = directory;
jsonFile = new File(dir.path + '/' + fileName);
jsonFile.createSync();
fileExists = jsonFile.existsSync();
print(fileExists);
if (fileExists) {
fileContent = jsonDecode(jsonFile.readAsStringSync());
setState(() {});
}
});
}
#override
void dispose() {
keyInputController.dispose();
valueInputController.dispose();
super.dispose();
}
void createFile(Map<String, String> content, Directory dir, String fileName) {
print('Creating file!');
File file = new File(dir.path + '/' + fileName);
file.createSync();
fileExists = true;
file.writeAsStringSync(json.encode(content));
}
void writeToFile(String key, String value) {
print('Writing to file');
Map<String, String> content = {key: value};
if (fileExists) {
print('File exists');
Map<String, String> jsonFileContent =
json.decode(jsonFile.readAsStringSync());
jsonFileContent.addAll(content);
jsonFile.writeAsStringSync(json.encode(jsonFileContent));
} else {
print('File does not exists!');
createFile(content, dir, fileName);
}
this.setState(() {
fileContent = json.decode(jsonFile.readAsStringSync());
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("JSON Tutorial"),
),
body: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.only(top: 10.0)),
new Text(
"File content: ",
style: new TextStyle(fontWeight: FontWeight.bold),
),
new Text((fileContent.toString() == '')
? 'PlaceHolder'
: fileContent.toString()),
new Padding(padding: new EdgeInsets.only(top: 10.0)),
new Text("Add to JSON file: "),
new TextField(
controller: keyInputController,
),
new TextField(
controller: valueInputController,
),
new Padding(padding: new EdgeInsets.only(top: 20.0)),
new ElevatedButton(
child: new Text("Add key, value pair"),
onPressed: () {
writeToFile(keyInputController.text, valueInputController.text);
})
],
),
);
}
}
Any idea what can happen?
First, you are creating a file
dir = directory;
jsonFile = new File(dir.path + '/' + fileName);
jsonFile.createSync();
then making sure it was created
fileExists = jsonFile.existsSync();
print(fileExists);
if (fileExists) {
...
}
And then if it was, you are reading its contents and parsing them as JSON
fileContent = jsonDecode(jsonFile.readAsStringSync());
setState(() {});
So The file you just created is empty, and so you are reading an empty file and passing an empty string into the jsonDecode function. which throws an error
You also declare this function, but never call it:
void createFile(Map<String, String> content, Directory dir, String fileName) {
print('Creating file!');
File file = new File(dir.path + '/' + fileName);
file.createSync();
fileExists = true;
file.writeAsStringSync(json.encode(content));
}
So I'm guessing what you actually wanted to do was something like this:
#override
void initState() {
super.initState();
getApplicationDocumentsDirectory().then((Directory directory) {
dir = directory;
createFile(content, dir, fileName);
print(fileExists);
if (fileExists) {
fileContent = jsonDecode(jsonFile.readAsStringSync());
setState(() {});
}
});
}
Also, the createFile method only uses class fields, so you don't need any arguments on it I don't think.
Ok, I already found my fault, the main problem is that this code was with the Dart 1 version and when trying to adapt it to Dart 2 I found the problem.
What happened is that when creating the json file it is empty so as it does not have any key, value, it seems that a Map<String, dynamic> is generated, since in one of the tests I was doing it gave me this error :
The following _TypeError was thrown building Home(dirty, state: HomeState # 5f124):
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, String>' of 'function result'
So I decided to change my fileContent from this:
late Map<String, String> fileContent;
to this:
late Map fileContent;
Then I decided to change all the logic to leave it like this:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(new MaterialApp(
home: new Home(),
));
}
class Home extends StatefulWidget {
#override
State createState() => new HomeState();
}
class HomeState extends State<Home> {
TextEditingController keyInputController = new TextEditingController();
TextEditingController valueInputController = new TextEditingController();
late File jsonFile;
late Directory directory;
bool fileExists = false;
late Map fileContent;
#override
void initState() {
super.initState();
getApplicationDocumentsDirectory().then((dir) async {
directory = dir;
jsonFile = File('${directory.path}/juegos.json');
await jsonFile.create();
fileExists = await jsonFile.exists();
print(fileExists);
if (fileExists) {
if (await jsonFile.readAsString() == '') {
fileContent = {};
} else {
fileContent = jsonDecode(await jsonFile.readAsString());
}
setState(() {});
}
});
}
createFile() async {
jsonFile = File('${directory.path}/juegos.json');
await jsonFile.create();
}
writeToFile(String key, String value) async {
if (fileExists) {
if (fileContent.containsKey(key)) {
fileContent.update(key, (v) => v = value);
} else {
fileContent.putIfAbsent(key, () => value);
}
jsonFile.writeAsString(jsonEncode(fileContent));
} else {
createFile();
}
fileContent = jsonDecode(await jsonFile.readAsString());
}
#override
void dispose() {
keyInputController.dispose();
valueInputController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("JSON Tutorial"),
),
body: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.only(top: 10.0)),
new Text(
"File content: ",
style: new TextStyle(fontWeight: FontWeight.bold),
),
new Text((fileExists) ? fileContent.toString() : 'Esta vacio'),
new Padding(padding: new EdgeInsets.only(top: 10.0)),
new Text("Add to JSON file: "),
new TextField(
controller: keyInputController,
),
new TextField(
controller: valueInputController,
),
new Padding(padding: new EdgeInsets.only(top: 20.0)),
new ElevatedButton(
child: new Text("Add key, value pair"),
onPressed: () {
writeToFile(keyInputController.text, valueInputController.text);
setState(() {});
})
],
),
);
}
}
Since the file was empty, it was necessary to put a condition of if it was empty that fileContent is equal to an empty map, and not equal to a total empty ...
And in my wirteToFile I simply verify that if fileContent already has the key that I want to write that I update or else add it, finally I update fileContent again.
Either way now fileContent is never empty. that that was the error, since it tried to read something where there was absolutely nothing.
Hope this helps someone and thanks for the help #h8moss in the end he was right and it was because the file was empty, although his change proposal did not help me, the only thing I had to do was verify that it was not empty and if it was, fill it at least with an empty map.
So thanks again.

How to navigate to the next Material page after getting Successful API response using Multipart request as Http body parameter?

I believe response.statusCode == 200 from my Api because its printing Uploaded! How can I store my API response in a variable (Lets say "jsonResponse") so that I can pass it to my new MaterialPage DieticianAfterDateSelectPage?
The Error:
The method '[]' was called on null.
Receiver: null
Tried calling: []("Status")
The relevant error-causing widget was
MaterialApp
lib\main.dart:19
//
Future<void> SaveCustomTestBooking() async {
var jsonResponse;
if (EncUserId.isNotEmpty) {
var postUri = Uri.parse("http://mkklklklklktBooking");
var request = http.MultipartRequest('POST',postUri);
request.fields['VisitDate'] = '_selectedDate';
request.fields['EncUserId'] = 'EncUserId';
request.files.add(new http.MultipartFile.fromBytes(
"UserFile", File(image!.path).readAsBytesSync(),
filename:"Image.jpg",
contentType: MediaType('image', 'jpg')));
request.send().then((response){
if (response.statusCode == 200) {
print("Uploaded!"); //From here.............
Navigator.push(context, MaterialPageRoute(builder: (context) => DieticianAfterDateSelectPage(rresponse:DieticianEncBookingIdModel.fromJson(jsonResponse),)));
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Somthing went wrong")));
throw Exception("Faild to fetch");
}
}
);}
My variable image contain my gallery image after method call.
final ImagePicker _picker = ImagePicker();
File? image;
var fileContent;
var fileContentBase64;
Function to get image from gallery
void filePicker() async {
final File? selectedImage =
await ImagePicker.pickImage(source: ImageSource.gallery);
print(selectedImage!.path);
setState(() {
image = selectedImage;
fileContent = image!.readAsBytesSync();
fileContentBase64 = base64.encode(fileContent);
});
}
It's not very clear how to help. I can see that you are passing a value to DieticianAfterDateSelectPage, and your error message. But you are asking how to store the value in a variable!
What you probably need is to understand the error message. You are getting it because you are calling the [] operator on null. You need to check how that's happening, and check the line number 19 in your main.dart as in the error message.
This is how I print my Multipart request body
Future<void> SaveCustomTestBooking() async {
var jsonResponse;
if (EncUserId.isNotEmpty) {
var response = http.MultipartRequest('POST',Uri.parse("http://myApiTestBooking"));
response.fields['VisitDate'] = _selectedDate;
response.fields['EncUserId'] = EncUserId;
response.fields['Description'] = testTextController.text;
response.files.add(new http.MultipartFile.fromBytes(
"UserFile", File(image!.path).readAsBytesSync(),
filename:"Image.jpg",
contentType: MediaType('image', 'jpg')));
response.send().then((response) async {
if (response.statusCode == 200){
isApiCallProcess = false;
final respBody = await response.stream.bytesToString();// this is how we print body for Multipart request
jsonResponse = json.decode(respBody.toString());
print(respBody);
print("Uploaded!");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Booked"),
backgroundColor: Color(0xFF00b3a4),
));
// Navigator.push(context,new MaterialPageRoute( builder: (context) =>new MyTestReqDetailsPage(),));
Navigator.push(context,new MaterialPageRoute( builder: (context) =>new Home2(),));
}
});
}
}

Flutter Failed to decode image. The provided image must be a Bitmap., null)

Creating custom Icon in Google Map in flutter shows error.
My pubspec.yaml file
assets:
- assets/truck.png
My Code is:
void getCustomIcon() async {
customIcon = await BitmapDescriptor.fromAssetImage(
ImageConfiguration(
devicePixelRatio: 2.5,
),
'assets/truck.png');
}
Error is:
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(error, Failed to decode image. The provided image must be a Bitmap., null)
E/flutter (15757): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:569:7)
E/flutter (15757): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:321:33)
define in stateclass
BitmapDescriptor customIcon ;
call in initState
getBytesFromAsset('assets/truck.png', 64).then((onValue) {
customIcon =BitmapDescriptor.fromBytes(onValue);
});
where function is
static Future<Uint8List> getBytesFromAsset(String path, int width) async {
ByteData data = await rootBundle.load(path);
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width);
ui.FrameInfo fi = await codec.getNextFrame();
return (await fi.image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List();
}
then in marker creation
markers.add(
Marker(
markerId: ....,
position: ....,
icon: customIcon ,
onTap: () {
....
}
)
);