I received this error when I run the project. I am using a JSON API from https://rapidapi.com/apidojo/api/yummly2.
This is error I got, Error: NoSuchMethodError: 'call' Dynamic call of object has no instance method 'call'. Receiver: Instance of '_JsonMap' Arguments: ["name"]
I don't understand why I can get the error, because there are no red lines on my code.
api_recipe.dart
import 'package:deliciouso/model/recipe.dart';
import 'package:http/http.dart' as http;
import 'package:deliciouso/model/api_recipe.dart';
class ApiRecipe {
static Future<List<Recipe>> getRecipe() async {
var uri = Uri.https('yummly2.p.rapidapi.com', '/feeds/list',
{"start": "0", "limit": "18", "tag": "list.recipe.popular"});
final response = await http.get(uri, headers: {
"x-rapidapi-key": "659d1b868cmsh981c45e6fe4147fp12524fjsna4689c3a42f3",
"x-rapidapi-host": "yummly2.p.rapidapi.com",
"useQueryString": "true"
});
Map data = jsonDecode(response.body);
List _temp = [];
for(var i in data['feed']){
_temp.add(i['content']['details']);
}
return Recipe.recipeFromSnapshot(_temp);
}
}
recipe.dart
final String name;
final String img;
final double rating;
final String time;
Recipe(
{required this.name,
required this.img,
required this.rating,
required this.time});
factory Recipe.fromJson(dynamic json) {
return Recipe(
name: json('name') as String,
img: json('img')[0]['hostedLargeURL'] as String,
rating: json('rating') as double,
time: json('time') as String);
}
static List<Recipe> recipeFromSnapshot(List snapshot) {
return snapshot.map((data) {
return Recipe.fromJson(data);
}).toList();
}
@override
String toString() {
return 'Recipe {name: $name, img: $img, rating: $rating, time: $time}';
}
}
recipe_card.dart
class RecipeCard extends StatelessWidget {
final String title;
final String rating;
final String cookTime;
final String url;
const RecipeCard(
{required this.title,
required this.rating,
required this.cookTime,
required this.url});
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 22, vertical: 10),
width: MediaQuery.of(context).size.width,
height: 250,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.6),
offset: Offset(0.0, 10.0),
blurRadius: 10.0,
spreadRadius: -6.0),
],
image: DecorationImage(
colorFilter: ColorFilter.mode(
Colors.black.withOpacity(0.35), BlendMode.multiply),
image: NetworkImage(url),
fit: BoxFit.cover),
),
child: Stack(
children: [
Align(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 5.0),
child: Text(title,
style: TextStyle(fontSize: 19),
overflow: TextOverflow.ellipsis,
maxLines: 2,
textAlign: TextAlign.center),
),
alignment: Alignment.center,
),
Align(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.all(5),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.4),
borderRadius: BorderRadius.circular(15)),
child: Row(
children: [
Icon(
Icons.stars,
color: Colors.yellow,
size: 18,
),
SizedBox(
width: 7,
),
Text(rating),
],
),
),
Container(
padding: EdgeInsets.all(5),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.4),
borderRadius: BorderRadius.circular(15)),
child: Row(
children: [
Icon(
Icons.schedule,
color: Colors.yellow,
size: 18,
),
SizedBox(
width: 7,
),
Text(cookTime),
],
),
),
],
),
alignment: Alignment.bottomLeft,
)
],
),
);
}
}
home.dart
import 'package:deliciouso/screens/widget/recipe_card.dart';
import 'package:flutter/material.dart';
import 'package:deliciouso/model/recipe.dart';
class Home extends StatefulWidget {
Home({Key? key}) : super(key: key);
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
late List<Recipe> _recipe;
bool _isLoading = true;
@override
void initState() {
super.initState();
getRecipe();
}
Future<void> getRecipe() async {
_recipe = await ApiRecipe.getRecipe();
setState(() {
_isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.restaurant_menu),
SizedBox(width: 10),
Text('Food Recipes')
],
),
),
body: _isLoading
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: _recipe.length,
itemBuilder: (context, index) {
return RecipeCard(
title: _recipe[index].name,
cookTime: _recipe[index].time,
rating: _recipe[index].rating.toString(),
url: _recipe[index].img,
);
},
));
}
}
main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Delicioso',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
primaryColor: Colors.white,
textTheme: TextTheme(bodyText2: TextStyle(color: Colors.white))),
home: Home(),
);
}
}
CodePudding user response:
Your Recipe.fromJson
method has some incorrect syntax. When accessing the members of a Map
, use the []
operator. Do not use ()
as you are doing currently.
factory Recipe.fromJson(dynamic json) {
return Recipe(
name: json['name'] as String,
img: json['img'][0]['hostedLargeURL'] as String,
rating: json['rating'] as double,
time: json['time'] as String);
}
()
will try to invoke the call
method of an object, which your object does not have, which is why you get the error "call of object has no instance method 'call'"