Issue
This is show type list dynamic is not a subtype of type map string dynamic" Now when i run emulator is show "type list dynamic is not a subtype of type map string dynamic" on my emulator how can i fix it ?
Now i want to create program about find api id form my emulator use text field and button when i put some number and click button is will show data or title of that ID , but I’m just beginner so if anyone thing my code is correct or not or you have some recommend pls tell me
My JSON
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Album> fetchAlbum() async {
final response =
await http.get(Uri.parse('http://192.168.176.131:3000/api/courses/'));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Album.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception1
throw Exception('Failed to load album');
}
}
class Album {
final int userId;
final int id;
final String title;
Album({
required this.userId,
required this.id,
required this.title,
});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
userId: json['userId'],
id: json['id'],
title: json['title'],
);
}
}
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late Future<Album> futureAlbum;
@override
void initState() {
super.initState();
futureAlbum = fetchAlbum();
}
Widget build(BuildContext context) {
TextEditingController searchController = new TextEditingController();
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),
),
body: Column(children: [
Container(
child: Row(children: [
Expanded(
flex: 2,
child: TextField(
controller: searchController
)
),
Expanded(
flex: 1,
child: FlatButton(
onPressed: () {
print(
"this is the text to search for => ${searchController
.text}");
},
child: Text("Search"),
)
)
],)
),
Center(
child: FutureBuilder<Album>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data!.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
),
],)
),
);
}
}
JSON Code
const Joi = require('joi');
const express = require('express');
const app = express();
app.use(express.json());
const courses = [
{ userId:1, id:1, title:'course 1'},
{ userId:2, id:2, title:'course 2'},
{ userId:3, id:3, title:'course 3'},
];
app.get('/', (req,res) => {
res.send('Hello world');
});
app.get('/api/courses',(req, res) => {
res.send(courses);
});
app.post('/api/courses', (req, res) => {
const { error } = validateCourse(req.body);
if (error)return res.status(400).send(error.details[0].message);
const course = {
id: courses.length +1,
name: req.body.name
};
courses.push(course);
res.send(course);
});
app.put('/api/courses/:id', (req, res) => {
const course = courses.find(c => c.id === parseInt(req.params.id));
if (!course) return res.status(404).send('The course with the given ID was not found.');
const {error} = validateCourse(req.body); //result.eror
if (error) return res.status(400).send(error.details[0].message);
//Update course
course.name = req.body.name;
res.send(course);
//Return the updated course
});
app.delete('/api/courses/:id', (req, res) => {
const course = courses.find(c => c.id === parseInt(req.params.id));
if (!course) return res.status(404).send('The course with the given ID was not found.');
const index = courses.indexOf(course);
courses.splice(index, 1);
res.send(course);
});
function validateCourse(course){
const schema = {
name: Joi.string().min(3).required()
};
return Joi.validate(course, schema);
}
app.get(‘/api/courses/:id’, (req, res) => {
const course = courses.find(c => c.id === parseInt(req.params.id));
if (!course) return res.status(404).send(‘The course with the given ID was not found.’);
res.send(course);
});
const port = process.env.PORT || 3000;
//app.listen(port, () => console.log(Listening on port ${port} ..
));
app.listen(3000, ‘0.0.0.0’);
Solution
You should cast the returned value from the jsonDecode to a Map <String, dynamic>
.
jsonDecode returns a dynamic
value, not a Map <String, dynamic>
as the Album.fromJson expects.
Answered By – Ricardo Parra
Answer Checked By – Willingham (FlutterFixes Volunteer)