I’m trying to build a flutter app that fetches and posts from an api, here is the code, I can’t seem to make the code render the posts on the UI, it comes back as black with a single white box. I have been debugging, the posts and fetches work fine ad the console logs the json being retrieved but somehow it can’t render on the UI.
import 'dart:convert';
import 'package:dawgs/Discussion.dart';
import 'package:dawgs/components/WallPost.dart';
import 'package:flutter/gestures.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:dawgs/components/text_field.dart';
import 'dart:developer' as developer;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'The Buzz',
theme: ThemeData(
colorScheme:
ColorScheme.fromSeed(seedColor: Color.fromARGB(255, 32, 7, 80)),
useMaterial3: true,
),
home: const MyHomePage(title: 'Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final titleController = TextEditingController();
final messageController = TextEditingController();
late Future<List<Discussion>> _future_list_discussions;
final backendUrl = "https://team-dawgs.dokku.cse.lehigh.edu";
@override
void initState() {
super.initState();
_future_list_discussions = fetchDiscussions();
}
@override
Widget build(BuildContext context) {
return build_v3(context);
}
Widget build_v3(BuildContext context) {
var fb = FutureBuilder<List<Discussion>>(
future: _future_list_discussions,
builder:
(BuildContext context, AsyncSnapshot<List<Discussion>> snapshot) {
Widget child;
if (snapshot.hasData) {
// developer.log('`using` ${snapshot.data}', name: 'my.app.category');
// create listview to show one row per array element of json response
child = ListView.builder(
//shrinkWrap: true, //expensive! consider refactoring. https://api.flutter.dev/flutter/widgets/ScrollView/shrinkWrap.html
padding: const EdgeInsets.all(16.0),
itemCount: snapshot.data!.length,
itemBuilder: /*1*/ (context, i) {
return Card(
child: Padding(
padding: const EdgeInsets.only(
top: 32.0, bottom: 32.0, left: 16.0, right: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
snapshot.data![i].title,
style: TextStyle(
fontSize: 22, fontWeight: FontWeight.bold),
),
Text(
snapshot.data![i].message,
style: TextStyle(
fontSize: 22, fontWeight: FontWeight.bold),
),
],
)),
);
});
} else if (snapshot.hasError) {
// newly added
child = Text('${snapshot.error}');
} else {
// awaiting snapshot data, return simple text widget
// child = Text('Calculating answer...');
child = const CircularProgressIndicator(); //show a loading spinner.
}
return child;
},
);
return fb;
}
}
/* // Post Discussion
Padding(
padding: const EdgeInsets.all(25.0),
child: Row(
children: [
Expanded(
child: MyTextField(
controller: titleController,
hintText: 'Title now!',
obscureText: false,
),
),
SizedBox(width: 10),
Expanded(
child: MyTextField(
controller: messageController,
hintText: 'Content please',
obscureText: false,
),
),
IconButton(
onPressed: () {
setState(() {
_future_list_discussions = postDiscussion(
titleController.text,
messageController.text,
);
});
},
icon: const Icon(Icons.arrow_circle_up),
)
],
),
)
],
),
),
);
} */
Future<List<Discussion>> postDiscussion(String title, String message) async {
final response = await http.post(
Uri.parse('https://team-dawgs.dokku.cse.lehigh.edu/discussions'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'mTitle': title,
'mMessage': message,
}),
);
if (response.statusCode == 200) {
final responseBody = jsonDecode(response.body);
// Check if the response body is in the expected format
if (responseBody is List<dynamic>) {
// Map each item in the list to a Discussion object
return responseBody.map((item) => Discussion.fromJson(item)).toList();
}
}
// Throw a generic error if any unexpected scenario occurs
throw Exception(
'Failed to post a discussion. Status code: ${response.statusCode}, Reason: ${response.reasonPhrase}');
}
Future<List<Discussion>> fetchDiscussions() async {
final response = await http
.get(Uri.parse('https://team-dawgs.dokku.cse.lehigh.edu/discussions'));
if (response.statusCode == 200) {
// If the server did return a 200 OK response, then parse the JSON.
final List<Discussion> returnData;
var res = jsonDecode(response.body);
print('json decode: $res');
if (res is List) {
returnData =
(res as List<dynamic>).map((x) => Discussion.fromJson(x)).toList();
} else if (res is Map) {
returnData = <Discussion>[
Discussion.fromJson(res as Map<String, dynamic>)
];
} else {
developer
.log('ERROR: Unexpected json response type (was not a List or Map).');
returnData = List.empty();
}
return returnData;
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Did not receive success status code from request.');
}
}
I tried different ways and different youtube videos to render it differently but nothing worked. Please help!
2
Answers
Where did you get the packages with dawgs/ ?
I think you missed adding the scaffold