I have been following Flutter Redux tutorial from youtube. The same is code is working in tutorial but when I implemented it, it's not working logically. Basically, I am fetching data from json file running on live server on my pc and there is no object display from json on the app. Can anyone suggest what is actually wrong.
Here is the code:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:redux/redux.dart';
import 'package:flutter_redux/flutter_redux.dart';
const apiUrl = 'http://127.0.0.1:5500/api/people.json';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
);
}
}
@immutable
class Person {
final String name;
final int age;
const Person({required this.name, required this.age});
Person.fromJson(Map<String, dynamic> json)
: name = json['name'] as String,
age = json['age'] as int;
@override
String toString() => 'Person ($name, $age years old )';
}
Future<Iterable<Person>> getPersons() async => HttpClient()
.getUrl(Uri.parse(apiUrl))
.then((req) => req.close())
.then((resp) => resp.transform(utf8.decoder).join())
.then((str) => json.decode(str) as List<dynamic>)
.then((list) => list.map((e) => Person.fromJson(e)));
@immutable
abstract class Action {
const Action();
}
@immutable
class LoadPeopleAction extends Action {
const LoadPeopleAction();
}
@immutable
class SuccessfullyFetchedPeopleAction extends Action {
final Iterable<Person> persons;
const SuccessfullyFetchedPeopleAction({required this.persons});
}
@immutable
class FailedToFetchPeopleAction extends Action {
final Object error;
const FailedToFetchPeopleAction({required this.error});
}
@immutable
class State {
final bool isLoading;
final Iterable<Person>? fetchedPersons;
final Object? error;
const State(
{required this.isLoading,
required this.fetchedPersons,
required this.error});
const State.empty()
: isLoading = false,
fetchedPersons = null,
error = null;
}
State reducer(State oldState, action) {
if (action is LoadPeopleAction) {
return const State(isLoading: true, fetchedPersons: null, error: null);
} else if (action is SuccessfullyFetchedPeopleAction) {
return State(isLoading: false, fetchedPersons: action.persons, error: null);
} else if (action is FailedToFetchPeopleAction) {
return State(
isLoading: false,
fetchedPersons: oldState.fetchedPersons,
error: action.error);
}
return oldState;
}
void loadPeopleMiddleware(
Store<State> store, dynamic action, NextDispatcher next) {
if (action is LoadPeopleAction) {
getPersons()
.then((persons) =>
store.dispatch(SuccessfullyFetchedPeopleAction(persons: persons)))
.catchError((e) => store.dispatch(FailedToFetchPeopleAction(error: e)));
}
next(action);
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final store = Store(reducer,
initialState: const State.empty(), middleware: [loadPeopleMiddleware]);
return Scaffold(
appBar: AppBar(
title: const Center(
child: Text('Flutter Redux Demo'),
),
),
body: StoreProvider(
store: store,
child: Column(children: [
TextButton(
onPressed: () {
store.dispatch(const LoadPeopleAction());
},
child: const Center(child: Text('Load Persons'))),
StoreConnector<State, bool>(
converter: (store) => store.state.isLoading,
builder: (context, isLoading) {
if (isLoading) {
return const CircularProgressIndicator();
} else {
return const SizedBox();
}
}),
StoreConnector<State, Iterable<Person>?>(
converter: (store) => store.state.fetchedPersons,
builder: (context, people) {
if (people == null) {
return const SizedBox();
} else {
return Expanded(
child: ListView.builder(
itemCount: people.length,
itemBuilder: (context, index) {
final person = people.elementAt(index);
return ListTile(
title: Text(person.name),
subtitle: Text('${person.age} years old.'),
);
}),
);
}
})
]),
),
);
}
}
And here is the people.json file I uploaded on live server.
[{
"name": "Foo",
"age": 20
},
{
"name": "Bar",
"age": 30
}, {
"name": "F",
"age": 20
}
]