Reputation: 541
I'm trying to learn making api calls in Flutter and make an app that'll be useful to me at least!
For this, I'm making a call to Nifty's(Stock Exchange in India) API: https://www.nseindia.com/api/option-chain-indices?symbol=NIFTY
I'm using the following code to achieve my goal
import 'dart:convert';
import 'package:http/http.dart';
final url = 'https://www.nseindia.com/api/option-chain-indices?symbol=NIFTY';
Future<Map<String, dynamic>> fetchNiftyData() async {
final response = await get(
Uri.parse(url),
);
Map<String, dynamic> responseBody = jsonDecode(response.body);
return responseBody;
}
It works. It returns data from the api as it is!!
BUT SOMETIMES IT DOESN'T. On restarting the app it might work again and might not work too. I don't want my app to be so inconsistent in calling the api.
This is the error stack I'm getting:
Restarted application in 3,418ms.
E/flutter ( 3901): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: FormatException: Unexpected character (at character 1)
E/flutter ( 3901): <!DOCTYPE html>
E/flutter ( 3901): ^
E/flutter ( 3901):
E/flutter ( 3901): #0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1404:5)
E/flutter ( 3901): #1 _ChunkedJsonParser.parseNumber (dart:convert-patch/convert_patch.dart:1271:9)
E/flutter ( 3901): #2 _ChunkedJsonParser.parse (dart:convert-patch/convert_patch.dart:936:22)
E/flutter ( 3901): #3 _parseJson (dart:convert-patch/convert_patch.dart:40:10)
E/flutter ( 3901): #4 JsonDecoder.convert (dart:convert/json.dart:506:36)
E/flutter ( 3901): #5 JsonCodec.decode (dart:convert/json.dart:157:41)
E/flutter ( 3901): #6 jsonDecode (dart:convert/json.dart:96:10)
E/flutter ( 3901): #7 fetchBankNiftyData
package:options_trader/Services/fetch_bank_nifty_data.dart:12
E/flutter ( 3901): <asynchronous suspension>
E/flutter ( 3901): #8 _BankNiftyScreenState.getBankNiftyData
package:options_trader/Screens/bank_nifty_screen.dart:21
E/flutter ( 3901): <asynchronous suspension>
E/flutter ( 3901):
Finally, this is the way I'm calling/using the fetched data...
import 'package:flutter/material.dart';
import '../Services/fetch_nifty_data.dart';
class NiftyScreen extends StatefulWidget {
@override
_NiftyScreenState createState() => _NiftyScreenState();
}
class _NiftyScreenState extends State<NiftyScreen> {
Map<String, dynamic>? niftyDetails = {};
@override
void initState() {
super.initState();
getNiftyDetails();
}
getNiftyDetails() async {
this.niftyDetails = await fetchNiftyData();
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: niftyDetails!.isNotEmpty
? ListView.builder(
itemCount: niftyDetails!["filtered"]["data"].length,
itemBuilder: (_, index) {
return ListTile(
title: Text(
'${niftyDetails!["filtered"]["data"][index]["strikePrice"]}'),
);
},
)
: LinearProgressIndicator(),
);
}
}
What am I doing wrong? And what's the best practice? TIA
Upvotes: 1
Views: 1264
Reputation: 12353
The <!DOCTYPE html>
error is caused when the API doesn't return the data you wanted in the format you are expecting, which is json, but it returns an error page, most likely a 404, which starts with <!DOCTYPE html>
, and not {"records":{"expiryDates"...etc]
which can be parsed using jsonDecode.
If it's working a few times, and others not, It's not your problem most likely, and it's perhaps caused by being rate limited by the API itself, which explains why it works again later, without you changing your code.
Upvotes: 1