Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: createComputedAsync Not Updating Correctly #358

Open
mcmah309 opened this issue Dec 2, 2024 · 3 comments
Open

Bug: createComputedAsync Not Updating Correctly #358

mcmah309 opened this issue Dec 2, 2024 · 3 comments

Comments

@mcmah309
Copy link
Contributor

mcmah309 commented Dec 2, 2024

Example

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:signals/signals_flutter.dart';

void main() {
  SignalsObserver.instance = LoggingSignalsObserver();
  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});

  ThemeData createTheme(BuildContext context, Brightness brightness) {
    return ThemeData(
      colorScheme: ColorScheme.fromSeed(
        seedColor: Colors.blue,
        brightness: brightness,
      ),
      brightness: brightness,
      useMaterial3: true,
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: createTheme(context, Brightness.light),
      darkTheme: createTheme(context, Brightness.dark),
      themeMode: ThemeMode.system,
      home: const CounterExample(),
    );
  }
}

class CounterExample extends StatefulWidget {
  const CounterExample({super.key});

  @override
  State<CounterExample> createState() => _CounterExampleState();
}

class _CounterExampleState extends State<CounterExample> with SignalsMixin {
  late final Signal<int> signal = createSignal(0);
  late final FutureSignal<int> computed = createComputedAsync(() async {
    await Future.delayed(const Duration(seconds: 2));
    return signal.value;
  });
  // Sync version works
  // late final Computed<int> computedSync = createComputed(() {
  //   return signal.value;
  // });

  void _increment() {
    signal.value++;
    // Works if uncommented
    // computed.reload();
  }

  @override
  Widget build(BuildContext context) {
    String state = switch (computed.value) {
      AsyncDataReloading<int>(:final value) => "Reloading: $value",
      AsyncDataRefreshing<int>(:final value) => "Refreshing: $value",
      AsyncData<int>(:final value) => "Data: $value",
      AsyncError<int>() => "Error",
      AsyncLoading<int>() => "Loading",
    };
    // String state = computedSync.value.toString();
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Counter'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'State is: ',
            ),
            Text(
              state,
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _increment,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

Behavior

The initial state is Loading then after two seconds Data: 0 is displayed. Which is expected. But, if the "increment" button is hit, the widget is rebuilt, but computed function is never called again, thus the result is still Data: 0.

The expected behavior, would be the once signal.value is updated through _increment, the state changes to Reloading: 0, then after two seconds, the state becomes Data: 1.

@mcmah309
Copy link
Contributor Author

mcmah309 commented Dec 2, 2024

Might be semi intended behavior, I see

It is important that signals are called before any async gaps with await.

In the docs. Makes sense, otherwise it wouldn't be known which signal the value was accessed from.

If I move signal.value before any await the state changes to Loading, while it should be Reloading: 0. But the final result is Data: 1, as expected.

@mcmah309 mcmah309 changed the title Bug: createComputedAsync Not Updating Bug: createComputedAsync Not Updating Correctly Dec 2, 2024
@rodydavis
Copy link
Owner

That is correct, this is to match Angular behavior! You can add them manually in the dependencies array

@mcmah309
Copy link
Contributor Author

mcmah309 commented Dec 2, 2024

So

the state changes to Loading, while it should be Reloading: 0

Seems like the only unintended behavior here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants