Exception: FormatException: Unexpected character (at character 1) - json

I'm new to flutter and learning through a tutorial about Flutter So I was following the same codes and already tried rewriting almost everything but when I started to run the app and i got that above error.
ERROR:flutter/lib/ui/ui_dart_state.cc(157)
Exception: FormatException: Unexpected character (at character 1)
E/flutter (14218):
My codes:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class Loading extends StatefulWidget {
#override
_LoadingState createState() => _LoadingState();
}
class _LoadingState extends State<Loading> {
void getTime() async {
Response response= await get('http://worldtimeapi.org/timezone/Europe/London');
Map data=jsonDecode(response.body);
print(data);
}
#override
void initState() {
// TODO: implement initState
super.initState();
getTime();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(
backgroundColor: Colors.blue[800],
title: Text('here is loading'),
),
body: Text("choose location screen"),
);
}
}

I think you mean this link: https://worldtimeapi.org/api/timezone/Europe/London.
Not this one:
Response response= await get('http://worldtimeapi.org/timezone/Europe/London');
The link I gave you above gives you a JSON response in which you decode in your app. You were linking to an actual webpage that doesn't give you a JSON response, that's why you got that error. I have also made it HTTPS so it's more secure in your app.

Related

how to get iamge from diffrent data api in flutter like this

I have my model for json, service to get api
I just dont know how to get image like this like this
from this json from this
the Ipone Mega is the carousel slider(4 images in json link), below the other is just column
if you could show it in carousel Slider i will be very grateful to you
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:my_work/apiService/fetch_data.dart';
import 'package:my_work/apiService/phone.dart';
class CarouselSliderData extends StatefulWidget{
const CarouselSliderData({super.key});
#override
State<CarouselSliderData> createState() => CarouselSliderDataState();
}
class CarouselSliderDataState extends State<CarouselSliderData> {
Phone? info;
#override
void initState() {
DioService.getDataMocky(
url:'https://run.mocky.io/v3/654bd15e-b121-49ba-a588-960956b15175'
).then((value) async {
if(value != null){
setState((){
info = value!;
});
}
}).catchError(
(value) => (value),
);
super.initState();
}
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image(image:)
],
);
}
}
Step 1: get the json from API. I call this variable is
Map<String, dynamic> json;
Step 2: As you can see, "home_store" of your json is a list of phones. Therefore, you create a model class called PhoneModel like this:
class PhoneModel {
int id;
bool isNew;
String title;
String subtitle;
String picture;
bool isBuy;
/// constructor
PhoneModel({this.id ...});
/// from json to class model
PhoneModel.fromJson(Map<String, dynamic> json) {
this.id = json["id"];
this.isNew = json["is_new"];
...
}
}
Then do like this to catch the list of items:
List<PhoneModel> listPhones = List<PhoneModel>.from(
(json['home_store'] as List).map((e) => PhoneModel.fromJson(e)),
);
Now your list of phone is variable listPhones. Url is field picture. Do Image.network or anythings else... Good luck!

How to display Json nested objects (maps) in Flutter?

I am new to flutter, I want to display json nested objects "nom" values (So I can later on create a tabBar using these values).
I am getting this error
type 'Null' is not a subtype of type 'Map<dynamic, dynamic>'
This is the json file I am working on
This is the main code
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'tabbarclass.dart';
Future<stations> fetchDonnee() async {
print('fetch0');
final response = await http.get(Uri.parse('uri'));
if (response.statusCode == 200) {
print('fecth1');
// If the server did return a 200 OK response, then parse the JSON.
return stations.fromJson(jsonDecode(response.body));
}
else {
// If the server did not return a 200 OK response, then throw an exception.
throw Exception('Failed to load album');
}
}
class MyApp3 extends StatefulWidget {
const MyApp3({Key? key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp3> {
late Future<stations> futureDonnee;
Timer? timer;
#override
void initState() {
print('initstate');
futureDonnee=fetchDonnee();
timer= Timer.periodic(const Duration(seconds:1), (Timer t){
futureDonnee=fetchDonnee();
setState(() {});
print('initstate1');}
);
print('hi1');
super.initState();
}
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
print('builder');
FutureBuilder f1;
print('ok');
Center(
child:
f1=FutureBuilder<stations>(
future: futureDonnee,
builder: (context, snapshot) {
if (snapshot.hasData) {
print(snapshot.data!.comp);
//snapshot.data!.comp.forEach((k, v) => print(k));
return Scaffold(
body: Container(
width: size.width,
height: 85,
margin: EdgeInsets.fromLTRB(20, 20, 20, 0),
padding: const EdgeInsets.fromLTRB(10, 0, 10, 20),
decoration: const BoxDecoration(
color: Colors.white
),
child: Text('${snapshot.data!.ond}',style: TextStyle(fontSize: 13)),
)
);
}
else if (snapshot.hasError) {
return Text('${snapshot.error}');}
// By default, show a loading spinner.
return const CircularProgressIndicator();
},
)
);
return f1;
}
}
This is the class I defined
class stations {
final Map ond;
final Map comp;
final Map gaz;
final Map eau;
final Map nom;
const stations({
required this.ond,
required this.comp,
required this.eau,
required this.gaz,
required this.nom,
});
factory stations.fromJson(Map<String, dynamic>json) {
return stations(
ond: json['ond'],
comp: json['comp'],
eau: json['eau'],
gaz: json['gaz'],
nom: json['nom'],
);
}
}
And this is the response I am getting
Any help is much appreciated.

ERROR : NoSuchMethodError: The method 'substring' was called on null

I'm trying this certain app (world-time app) and constantly getting this error:
Used this HTTP Package for url:
import 'dart:convert';
import 'package:http/http.dart';
import 'package:intl/intl.dart';
class WorldTime {
String location;
String time;
String flag;
String url;
WorldTime({this.location, this.flag, this.url});
Future<void> getTime() async {
try {
Response response =
await get(Uri.https('worldtimeapi.org', 'api/timezone/$url'));
Map data = jsonDecode(response.body);
String datetime = data['datetime'];
String offset = data['utc_offset'].substring(1, 3);
DateTime now = DateTime.parse(datetime);
now = now.add(Duration(hours: int.parse(offset)));
time = DateFormat.jm().format(now);
} catch (e) {
print("Error occured: $e");
time = "Cannot Display Time Due to Error Occured";
}
}
}
imported world time api in this file:
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:world_time_app/services/world_time.dart';
class loading extends StatefulWidget {
#override
_loadingState createState() => _loadingState();
}
class _loadingState extends State<loading> {
void setTime() async {
WorldTime instance =
WorldTime(location: 'Florida', flag: 'img.jpg', url: 'America/Florida');
await instance.getTime();
Navigator.pushReplacementNamed(context, '/home', arguments: {
'location' : instance.location,
'flag': instance.flag,
'time': instance.time,
});
}
#override
void initState() {
super.initState();
setTime();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.all(50.0),
child: Text('Loading'),
));
}
}
pls help me Im getting error while running the app:
Restarted application in 1,228ms.
I/flutter (24197): Error occured: NoSuchMethodError: The method 'substring' was called on null.
I/flutter (24197): Receiver: null
I/flutter (24197): Tried calling: substring(1, 3)
I/flutter (24197): {location: Florida, flag: img.jpg, time: Cannot Display Time Due to Error Occured}
I think I made DateTime Object thats why it is showing error, is there any alternative to this?
Any help will be much appreciated :)
The error you are getting is most likely because utc_offset is null.
You can check if it's actually null or not, and that it's length is at least 3 before performing substring(1,3) on it, like this:
String offset =
data['utc_offset'] == null || data['utc_offset'].length >= 3
? "utc offset has a problem"
: data['utc_offset'].substring(1, 3);

How to parse the nested json in flutter

I am having the nested json where I want parse the worksheetData and display the list of worksheetdata in separate cards. I have tried used online tool parse but when I print the data it throws an error called "type 'List' is not a subtype of type 'Map"
#Update
Below is the home.dart file where I am getting the data error
Home.dart
class WorkSheet extends StatefulWidget {
const WorkSheet({Key key}) : super(key: key);
#override
_WorkSheetState createState() => new _WorkSheetState();
}
class _WorkSheetState extends State<WorkSheet> {
Future<String> loadSheetDataFromAssets() async {
return await DefaultAssetBundle.of(context)
.loadString('assets/example.json');
}
Future loadSheetData() async {
String jsonString = await loadSheetDataFromAssets();
final jsonResponse = json.decode(jsonString);
SheetData sheetData = new SheetData.fromJson(jsonResponse);
print('PName : ${sheetData.projectName}');
print('Worksheet : ${sheetData.worksheetData}');
print(sheetData);
}
#override
void initState() {
super.initState();
loadSheetData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Work sheet data'),
),
body: FutureBuilder(
future: loadSheetData(),
builder: (context, snapshot){
if(snapshot.data == null){
return Center(child: Text(snapshot.error));
}else{
return Card(child: Text(snapshot.data.toString()));
}
}
)
);
}
}
You could use some external tools to generate your models like quicktype
Or any of the approaches described in the official documentation doc
Make sure your class classes you want to convert fromJson are annotated with #JsonSerializable(). Please follow flutter documentation for this https://flutter.dev/docs/development/data-and-backend/json
This with Autoatically convert all your nested classes that are declared with #JsonSerializable() but if you have to convert a list from Json, you have to write some extra code like this below
Map jsonObject = json.decode(jsonString);
Iterable list = json.decode(jsonObject['worksheetData']);
List<WorksheetData> datasheet = list.map((f) => WorksheetData.fromJson(f)).toList();

Black screen on app launch when using i18n from JSON files

I am attempting to build my own implementation of a system for localizing strings for internationalization in Flutter apps, using Flutter's LocalizationsDelegate, and loading the localized strings from JSON files (one json file for each locale).
Everything works fine, but when the app is launched, there's a lapse of some milliseconds in which the screen goes black. The reason for this is that, since I am loading the JSON files using json.decode, the way I am retrieving the localized strings is asynchronous. The app loads its MaterialApp widget and then starts parsing the JSONs for localization. That is when the app goes black until it parses the JSON successfully.
Here is my implementation of my i18n system:
class Localization extends LocaleCodeAware with LocalizationsProvider {
Localization(this.locale) : super(locale.toString());
final Locale locale;
static Localization of(BuildContext context) =>
Localizations.of<Localization>(context, Localization);
}
class AppLocalizationsDelegate extends LocalizationsDelegate<Localization> {
const AppLocalizationsDelegate();
#override
bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);
#override
Future<Localization> load(Locale locale) async {
final localization = Localization(locale);
await localization.load();
return localization;
}
#override
bool shouldReload(AppLocalizationsDelegate old) => false;
}
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:example/resources/asset_paths.dart' as paths;
abstract class LocaleCodeAware {
LocaleCodeAware(this.localeCode);
final String localeCode;
}
mixin LocalizationsProvider on LocaleCodeAware {
static Map<String, String> _values;
Future<void> load() async {
final string = await rootBundle.loadString('${paths.i18n}$localeCode.json');
final Map<String, dynamic> jsonMap = json.decode(string);
_values = jsonMap.map((key, value) => MapEntry(key, value.toString()));
}
String get appTitle => _values['appTitle'];
}
Here is my main.dart file, with its MaterialApp widget.
import 'package:flutter/material.dart';
void main() => runApp(ExampleApp());
class ExampleApp extends StatelessWidget {
#override
Widget build(BuildContext context) => MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue),
localizationsDelegates: [
const AppLocalizationsDelegate(),
],
supportedLocales: const [Locale("en"), Locale("es")],
home: const AppNavigator(),
);
}
If instead of having the localized strings in JSON files, I assign a Map<String, String> to my _values map, and I load the strings directly from there, the black screen issue is gone, because the values are hardcoded and can be loaded synchronously.
So my question is, how can I have my app wait in splash screen until the localized strings are loaded from the JSON files?
Do you have any errors in your logs? The black screen could only be caused by 1. The current route not building a visible page or 2. The build() function of the current route throwing exceptions.
As for loading the localizations while on the splash screen, you can do that within your main() function:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
List<Locale> locales = WidgetsBinding.instance.window.locales;
// ... logic to decide which locale to use and load localizations for
final string = await rootBundle.loadString('${paths.i18n}$localeCode.json');
final Map<String, dynamic> jsonMap = json.decode(string);
runApp(ExampleApp(jsonMap));
}
This way, you can read the JSON file and convert it to a Map while on the splash screen, and then pass it to ExampleApp, which can in turn pass it to AppLocalizationsDelegate, which can store it as a local variable and use it within load().
checkout easy_localization package , its simpler than the most out there