Search code examples
jsonfluttergoogle-places-apiflutter-futurebuilderflutter-http

How to display Future result (error) in Flutter


i am trying to build a address search with Places API. But I don't know how to show the results.

The Searchfield class

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:loci/services/place_service.dart';

class addressSearch extends SearchDelegate<Suggestion> {

  searchAddress(sessionToken) {
  apiClient = PlaceApiProvider(sessionToken);
  }
  PlaceApiProvider? apiClient;

@override
  List<Widget>? buildActions(BuildContext context) {
    // TODO: implement buildActions
    return [
      IconButton(
        onPressed: (){
          query = '';
        }, 
        icon: Icon(Icons.clear))
    ];
  }

  @override
  Widget? buildLeading(BuildContext context) {
    // TODO: implement buildLeading
    return 
      IconButton(
        onPressed: (){
          //close(context, null);
        }, 
        icon: Icon(Icons.arrow_back));
  }

  @override
  Widget buildResults(BuildContext context) {
    // TODO: implement buildResults
    return Center(child: Text("Adresse nicht gefunden"));
  }

  PlaceApiProvider result = PlaceApiProvider(Client);
  @override
  Widget buildSuggestions(BuildContext context) {
    print('counter value :');
    final PlaceApiProvider requests = PlaceApiProvider(PlaceApiProvider);
    // TODO: implement buildSuggestions
    return FutureBuilder(
      future: query == ""
          ? null
          : result.fetchSuggestions(),
      builder: (context, snapshot) => query == ''
      ? Container(
        padding: EdgeInsets.all(16),
        child: Text("Gib deine Unternehmensadresse an"),
      )
      : snapshot.hasData
        ? ListView.builder(
          itemBuilder: (context, index) => ListTile(
          //data = snapshot.data[index] as Suggestion;
            //Data return here
            title: Text((snapshot.data[index] as Suggestion).description), 
            onTap: () {
              close(context, snapshot.data as Suggestion);
            },
            
          ),
          itemCount: (snapshot.data as dynamic).length,
          )
          : Center(child: Text('lädt...')),
    );
  }
}

But flutter marks the opening bracket of "[index]" saying:

the method []' can't be unconditionally invoked because the receiver can be 'null'

title: Text((snapshot.data[index] as Suggestion).description),

If I change it to : title: Text((snapshot.data?[index] as Suggestion).description), flutter says:

the operator ' []' isn't defined for the type 'object'. try defining the operator '[]'

API call class

import 'dart:convert';
import 'dart:developer';
import 'dart:io';

import 'package:http/http.dart' as http;
import 'package:http/http.dart';

class Suggestion {
  final String placeId;
  final String description;

  Suggestion(this.placeId, this.description);


  @override
  String toString() {
    return 'Suggestion(description: $description, placeId: $placeId';
  }
}

class PlaceApiProvider {
  final client = new Client();

  PlaceApiProvider(this.sessionToken);

  final sessionToken;

  // static final String androidKey = 'XYZ';
  // static final String iosKey = 'XYZ';
  // final apiKey =  Platform.isAndroid ? androidKey : iosKey;
  
  Future<List<Suggestion>> fetchSuggestions() async {
    print('counter value : RESPONSE');
    const request = 'https://maps.googleapis.com/maps/api/place/autocomplete/json?input=TEST&types=address&components=country:de&key=XYZ';
    final response = await client.get(Uri.parse(request));

    if (response.statusCode == 200) {
      final result = json.decode(response.body);
      if (result['status'] == 'OK') {
          
        //Compose Suggestions in a List
        return result['predictions']
         .map<Suggestion>((p) => Suggestion(p['place_id'], p['description']))
         .toList();
      }
      if (result['status'] == 'ZERO_RESULTS') {
          print('keine ergebnisse');
        return [];
      }
          print('error');
      throw Exception(result['error_message']);
    } else {
          print('fehler beim laden');
      throw Exception('Failed to fetch suggestion');
    }
   // throw ArgumentError.notNull();
  }


}```

The API does work and returns a json, but I don't know how to get the descriptions or the placeId. 

I am on this for days and would be so thankful if somebody can help me.

Solution

  • What you need to do is:

    final suggestion = snapshot.data as Suggestion?;
    

    the reason that you don't have anywhere to write this line, is because the code is poorly written. Refactor it by breaking it into widgets, nicely written "if" statements, then figure out the problem.