How can I get my code (Flutter using Freezed) to obtain use of the "copyWith" freezed feature for updating state here?
Freezed Class:
import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'todo_list.freezed.dart';
part 'todo_list.g.dart';
@freezed
class TodoList with _$TodoList {
const TodoList._();
factory TodoList({ required List<String> titles }) = _TodoList;
factory TodoList.loading() = Loading;
factory TodoList.error([String? message]) = ErrorDetails;
factory TodoList.fromJson(Map<String, dynamic> json) => _$TodoListFromJson(json);
}
State Notifier
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:gc_todo/presentation/state/todo_list.dart';
import 'dart:developer' as developer;
final todoListProvider = StateNotifierProvider((ref) => TodoListNotifier());
class TodoListNotifier extends StateNotifier<TodoList> {
TodoListNotifier() : super( TodoList(titles: ["first", "second"]) );
void addTodoList(String newTitle) {
developer.log("addTodoList - $state");
if (state is List<String>) (List<String> stateToUse) {
stateToUse.copyWith(); // STILL DOES NOT RECOGNISE "copyWith"
};
}
}
Freezed uses wrapper types around each variant of your union type, in this case TodoList
. The "list" variant of that type is not List<String>
as you seem to be assuming.
Also, copyWith
only works with properties defined in all union variants, which in your case is none.
You should use when
to "pattern match" over all variants of that type, or maybeWhen
to match a sub-set only.
Here's something that should work in your case:
class TodoListNotifier extends StateNotifier<TodoList> {
TodoListNotifier() : super( TodoList(titles: ["first", "second"]) );
void addTodoList(String newTitle) {
developer.log("addTodoList - $state");
state.maybeWhen(
(items) => setState(TodoList(titles: [...items, newTitle]),
orElse: () { /* TODO */ }
);
}
}