Я пишу пример использования Redux для управления моим состоянием. Я не знаю почему, но когда я запускаю свое приложение, моя консоль выдает мне сообщение об ошибке такого типа:
The getter 'length' was called on null.
Receiver: null
Tried calling: length
Я только начинающий в использовании избыточности, поэтому, пожалуйста, простите, если это будет просто маленькая забавная ошибка:)
Я вставляю код ниже: order_screen.dart
class OrdersScreen extends StatelessWidget{
void handleInitialBuild(OrdersScreenProps props){
props.getOrders();
}
@override
Widget build(BuildContext context){
return StoreConnector<AppState, OrdersScreenProps>(
converter: (store) => mapStateToProps(store),
onInitialBuild: (props) => this.handleInitialBuild(props),
builder: (context, props){
List<Order> data = props.listResponse.data;
bool loading = props.listResponse.loading;
Widget body;
if(loading){
body = Center(
child: CircularProgressIndicator(),
);
}else{
body = ListView.separated(
padding: const EdgeInsets.all(16.0),
itemCount: data.length,
separatorBuilder: (context, index) => Divider(),
itemBuilder: (context, i) {
Order order = data[i];
return ListTile(
title: Text(
order.title,
),
onTap: () {
props.getOrderDetails(order.id);
Navigator.pushNamed(context, AppRoutes.orderDetails);
},
);
},
);
}
return Scaffold(
appBar: AppBar(
title: Text('Orders list'),
),
body: body,
);
},
);
}
}
class OrdersScreenProps {
final Function getOrders;
final Function getOrderDetails;
final ListOrdersState listResponse;
OrdersScreenProps({
this.getOrders,
this.listResponse,
this.getOrderDetails,
});
}
OrdersScreenProps mapStateToProps(Store<AppState> store) {
return OrdersScreenProps(
listResponse: store.state.order.list,
getOrders: () => store.dispatch(getOrders()),
getOrderDetails: (int id) => store.dispatch(getOrderDetails(id)),
);
}
order_actions.dart
const LIST_ORDERS_REQUEST = 'LIST_ORDERS_REQUEST';
const LIST_ORDERS_SUCCESS = 'LIST_ORDERS_SUCCESS';
const LIST_ORDERS_FAILURE = 'LIST_ORDERS_FAILURE';
RSAA getOrdersRequest(){
return RSAA(
method: 'GET',
endpoint: 'http://10.0.2.2:80/order',
types: [
LIST_ORDERS_FAILURE,
LIST_ORDERS_REQUEST,
LIST_ORDERS_SUCCESS
],
headers: {
'Content-Type':'application/json',
},
);
}
ThunkAction<AppState> getOrders() => (Store<AppState> store) => store.dispatch(getOrdersRequest());
const GET_ORDERS_DETAILS_REQUEST = 'GET_ORDERS_DETAILS_REQUEST';
const GET_ORDERS_DETAILS_SUCCESS = 'GET_ORDERS_DETAILS_SUCCESS';
const GET_ORDERS_DETAILS_FAILURE = 'GET_ORDERS_DETAILS_FAILURE';
RSAA getOrderDetailsRequest(int id){
return RSAA(
method: 'GET',
endpoint: 'http://10.0.2.2:80/order/$id',
types: [
GET_ORDERS_DETAILS_REQUEST,
GET_ORDERS_DETAILS_SUCCESS,
GET_ORDERS_DETAILS_FAILURE
],
headers: {
'Content-Type':'application-type',
},
);
}
ThunkAction<AppState> getOrderDetails(int id) => (Store<AppState> store) => store.dispatch(getOrderDetailsRequest(id));
order_state.dart
class OrderState{
ListOrdersState list;
OrderDetailsState details;
OrderState({
this.list,
this.details,
});
factory OrderState.initial() => OrderState(
list: ListOrdersState.initial(),
details: OrderDetailsState.initial(),
);
}
class ListOrdersState {
dynamic error;
bool loading;
List<Order> data;
ListOrdersState({
this.error,
this.loading,
this.data,
});
factory ListOrdersState.initial() => ListOrdersState(
error: null,
loading: false,
data: [],
);
}
class OrderDetailsState {
dynamic error;
bool loading;
OrderDetails data;
OrderDetailsState({
this.error,
this.loading,
this.data,
});
factory OrderDetailsState.initial() => OrderDetailsState(
error: null,
loading: false,
data: null,
);
}
app_state.dart
@immutable
class AppState {
final UserState user;
final OrderState order;
AppState({
this.user,
this.order
});
factory AppState.initial() => AppState(
user: UserState.initial(),
order: OrderState.initial()
);
AppState copyWith({
UserState user,
OrderState order,
}) {
return AppState(
user: user ?? this.user,
order: order ?? this.order,
);
}
order_reducer.dart
OrderState orderResucer(OrderState state, FSA action){
OrderState newState = state;
switch (action.type) {
case LIST_ORDERS_REQUEST:
newState.list.error = null;
newState.list.loading = true;
newState.list.data = null;
return newState;
case LIST_ORDERS_SUCCESS:
newState.list.error = null;
newState.list.loading = false;
newState.list.data = ordersFromJSONStr(action.payload);
return newState;
case LIST_ORDERS_FAILURE:
newState.list.error = action.payload;
newState.list.loading = false;
newState.list.data = null;
return newState;
case GET_ORDERS_DETAILS_REQUEST:
newState.details.error = null;
newState.details.loading = true;
newState.details.data = null;
return newState;
case GET_ORDERS_DETAILS_SUCCESS:
newState.details.error = null;
newState.details.loading = false;
newState.details.data = orderFromJSONStr(action.payload);
return newState;
case GET_ORDERS_DETAILS_FAILURE:
newState.details.error = action.payload;
newState.details.loading = false;
newState.details.data = null;
return newState;
default:
return newState;
}
}
List<Order> ordersFromJSONStr(dynamic payload) {
Iterable jsonArray = json.decode(payload);
return jsonArray.map((j) => Order.fromJSON(j)).toList();
}
OrderDetails orderFromJSONStr(dynamic payload) {
return OrderDetails.fromJSON(json.decode(payload));
}