this is my http request.
import 'dart:convert';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:friendnpal/models/articles_model.dart';
import 'package:http/http.dart';
class ApiServices {
String endpoint =
'https://friendnpalapp-production-0d46.up.railway.app/api/article/random_daily';
Future<List<ArticlesModel>> getArticles() async {
Response response = await get(Uri.parse(endpoint));
if (response.statusCode == 200) {
final List result = jsonDecode(response.body);
print(response.body);
return result.map(((e) => ArticlesModel.fromJson(e))).toList();
} else {
print('error');
throw Exception(response.reasonPhrase);
}
}
}
`
final articlesProvider = Provider<ApiServices>((ref) => ApiServices());`
this is where is use the data
`import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';`
import 'package:friendnpal/models/articles_model.dart';
import '../../../data_provider.dart';
import '../../../in_app_browser/in_app_browser_screen.dart';
import '../../../utils/app_colors.dart';
import '../../../utils/app_strings.dart';
class ArticlesWidget extends ConsumerWidget {
const ArticlesWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final _data = ref.watch(articlesDataProvider);
return _data.when(
data: (_data) {
List<ArticlesModel> articlesList = _data.map((e) => e).toList();
return ListView.builder(
itemCount: articlesList.length,
itemBuilder: (context, index) {
return Container(
padding: const EdgeInsets.fromLTRB(18, 19, 18, 7),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
gradient: const LinearGradient(
colors: [
Color(0xff5F7AFF),
Color(0xff04D486),
],
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(bottom: 24),
alignment: Alignment.center,
child: const Text(
'Article of the day',
style: TextStyle(
fontSize: 20,
color: AppColors.white,
fontFamily: AppStrings.fontName),
),
),
Text(
articlesList[index].content!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: AppColors.white,
fontFamily: AppStrings.fontName),
),
GestureDetector(
onTap: () {
Navigator.push(
context,
/// navigate to inAppBrowser
MaterialPageRoute(
builder: (context) => InAppBrowserPage(
articlesList: articlesList[index],
)));
},
child: Container(
padding: EdgeInsets.all(10),
margin: const EdgeInsets.only(top: 39),
decoration: BoxDecoration(
color: AppColors.blue,
borderRadius: BorderRadius.circular(72)),
child: const Text(
'Read More',
style: TextStyle(
fontSize: 15,
color: AppColors.white,
fontFamily: AppStrings.fontName),
),
),
)
],
),
);
},
);
},
error: (err, s) => Text(err.toString()),
loading: () => Center(
child: CircularProgressIndicator(),
));
}
}
plese i need to know what caused the error also
It most likely goes wrong on
final List result = jsonDecode(response.body);
because the response is not a list.
The error indicates that it is a map.
In other words, your response.body
is of the form
{
...
}
and not
[
...
]
maybe in your case you have something like
{
"data" : [
...
]
}
In that case you need to replace the code to
final List result = jsonDecode(response.body)['data'];
EDIT:
I just tried out the url and can see that this is the response
{
"_id": "647c410f5504275bc960719b",
"articleID": "2",
"title": "Mastering the Art of Time Managemen",
"content": "Learn effective strategies and practical tips to manage your time efficiently. Boost your productivity, prioritize tasks, and strike a balance between work and personal life.",
"link": "https://www.example.com/article1",
"selectedDate": "2023-06-06T00:00:00.000Z",
"selectedWeek": null,
"__v": 0
}
As you can see this is a single article, but you are trying to parse it as if it's a list. The easiest fix would then be to wrap it in a list, like this for example:
final List result = [jsonDecode(response.body)];