Manish Paul
Manish Paul

Reputation: 541

Flutter http request sometimes shows error

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

Answers (1)

Huthaifa Muayyad
Huthaifa Muayyad

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

Related Questions