so i started with a new Screen where the User can input his favorite Band. The Plan is to display an image of this Band underneath the input field after the user clicked the Button "Search"
Im using the Wikipedia API for this. Now the Problem: If i enter a Bandname like "Linkin Park" and click on the Button nothing will show up. If i delete the last character of the Bandname(in this example "k") the app shows the correct image. When i enter the API Link in the browser with the correct Bandname it will show me the correct data.
Storing the Data in Firestore works perfectly fine. Just this little problem.
`
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class FavoriteBandScreen extends StatefulWidget {
@override
_FavoriteBandScreenState createState() => _FavoriteBandScreenState();
}
class _FavoriteBandScreenState extends State<FavoriteBandScreen> {
final _auth = FirebaseAuth.instance;
final _firestore = FirebaseFirestore.instance;
String _favoriteBand = '';
String _bandImageUrl = '';
Future _getBandImage() async {
// Rufe die Wikipedia-Seite der Band auf
String encodedBandName = _favoriteBand.replaceAll(' ', ' ');
http.Response response = await http.get(Uri.parse(
'https://en.wikipedia.org/w/api.php?format=json&action=query&prop=pageimages&titles=$encodedBandName&pithumbsize=400'));
// Parse die Antwort als JSON
Map<String, dynamic> jsonData = json.decode(response.body);
// Hole die URL des Bandbilds
if (jsonData['query'] != null && jsonData['query']['pages'] != null) {
String pageKey = jsonData['query']['pages'].keys.first;
if (jsonData['query']['pages'][pageKey] != null &&
jsonData['query']['pages'][pageKey]['thumbnail'] != null) {
_bandImageUrl =
jsonData['query']['pages'][pageKey]['thumbnail']['source'];
} else {
_bandImageUrl = '';
}
} else {
_bandImageUrl = '';
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Lieblingsband eingeben'),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Gib deine Lieblingsband ein:'),
TextField(
onChanged: (value) {
setState(() {
if (value.isEmpty) {
_favoriteBand = "";
} else {
_favoriteBand = value;
}
});
},
),
SizedBox(height: 20),
_bandImageUrl == ''
? CircularProgressIndicator()
: Image.network(_bandImageUrl),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Holle das Bandbild
if (_favoriteBand != '') {
_getBandImage();
}
// Speichere die Lieblingsband in der Cloud-Datenbank
User currentUser = FirebaseAuth.instance.currentUser!;
_firestore.collection('users').doc(currentUser.uid).set({
'favoriteBand': _favoriteBand,
'bandImageUrl': _bandImageUrl,
}, SetOptions(merge: true));
},
child: Text('Suchen'),
),
],
),
),
);
}
}
`
Ignore the german comments :) thanks for your help
I tryed encoding the Bandname with replacing spaces with "_" and " %". Both nosuccess i also tryed adding a space in the value which is used inthe Widget build to handoverr the String_favoriteBand
CodePudding user response:
wie geht's? Ich spreche auch Deutsch, werde aber nur auf Englisch antworten.
WIKIPEDIA's API call looks great. no need to "encoding" the band name LOL :)
Take a close look at how you handled _bandImageUrl
.
_getBandImage()
is an async function that by default has a delay. to be able to use _bandImageUrl
you need to manage its state. To do that you first need to rearrange your codebase by introducing initState
. Call _getBandImage()
within the initState
and change:
_bandImageUrl = jsonData['query']['pages'][pageKey]['thumbnail']['source'];
TO
image = jsonData['query']['pages'][pageKey]['thumbnail']['source'];
// check if mounted before using `setState` to avoid state error as we are working on the `initState`
if (mounted) {
setState(() => _bandImageUrl = image);
}
NOTE
This is not the best/better way. You should consider looking into using Models for your API organization and providers to implement its service calls.
If you are still having problems. Let me know right here.
Tschau!!!