Recommand · October 16, 2021 0

The argument type 'StateProvider<MainPageDataController?>' can't be assigned to the parameter type 'ProviderBase<Object?, MainPageDataController?>'

I am trying to get the data from API to fetch details of movies.

I am getting two errors on line 31 and 32.

This on line 31 –

The argument type 'StateProvider<MainPageDataController?>' can't be assigned to the parameter type 'ProviderBase<Object?, MainPageDataController?>'   

This on line 32, on the "state" word –

The getter 'state' isn't defined for the type 'StateProvider<MainPageDataController?>'.
Try importing the library that defines 'state', correcting the name to the name of an existing getter, or defining a getter or field named 'state'

Here is the code –

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:movie_app/controllers/main_page_data_controller.dart';
import 'package:movie_app/model/main_page_data.dart';
import 'package:movie_app/model/movie.dart';
import 'package:movie_app/model/search_category.dart';
import 'package:movie_app/widgets/movie_tile.dart';

final mainPageDataControllerProvider =
    StateProvider<MainPageDataController?>((ref) {
  return MainPageDataController();
});

class MainPage extends ConsumerWidget {
  double? _deviceHeight;
  double? _deviceWidth;

  MainPageDataController? _mainPageDataController;
  MainPageData? _mainPageData;

  TextEditingController? _searchTextFieldController;

  @override
  Widget build(BuildContext context, ScopedReader watch) {
    _deviceHeight = MediaQuery.of(context).size.height;
    _deviceWidth = MediaQuery.of(context).size.width;
    _searchTextFieldController = TextEditingController();

    _mainPageDataController = watch(mainPageDataControllerProvider);
    _mainPageData = watch(mainPageDataControllerProvider.state);

    return _buildUI();
  }

  Widget _buildUI() {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      backgroundColor: Colors.black,
      body: Container(
        height: _deviceHeight,
        width: _deviceWidth,
        child: Stack(
          alignment: Alignment.center,
          children: [
            _backgroundWidget() ?? const Text('No image to load'),
            _foregroundWidget() ?? const Text('No Foreground to load'),
          ],
        ),
      ),
    );
  }

  Widget? _backgroundWidget() {
    return Container(
      height: _deviceHeight,
      width: _deviceWidth,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(10.0),
        image: const DecorationImage(
          image: NetworkImage(
            'https://c4.wallpaperflare.com/wallpaper/474/998/395/cillian-murphy-tom-hardy-dunkirk-best-movies-wallpaper-preview.jpg',
          ),
          fit: BoxFit.cover,
          //image: AssetImage('assets/images/logo.png'),
        ),
      ),
      child: BackdropFilter(
        filter: ImageFilter.blur(sigmaX: 40.0, sigmaY: 40.0),
        child: Container(
          decoration: BoxDecoration(
            color: Colors.black.withOpacity(0.2),
          ),
        ),
      ),
    );
  }

  Widget? _foregroundWidget() {
    return Container(
      padding: EdgeInsets.only(top: _deviceHeight! * 0.02),
      width: _deviceWidth! * 0.88,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        mainAxisSize: MainAxisSize.max,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          _topBarWidget() ??
              const SizedBox(
                child: Text(
                  "Can't load Bar",
                  style: TextStyle(color: Colors.white),
                ),
              ),
          Container(
            height: _deviceHeight! * 0.83,
            padding: EdgeInsets.symmetric(vertical: _deviceHeight! * 0.01),
            child: _moviesListViewWidget(),
          ),
        ],
      ),
    );
  }

  Widget? _topBarWidget() {
    return Container(
      height: _deviceHeight! * 0.08,
      decoration: BoxDecoration(
        color: Colors.black54,
        borderRadius: BorderRadius.circular(20.0),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          searchFieldWidget(),
          _categorySelectionWidget(),
        ],
      ),
    );
  }

  Widget searchFieldWidget() {
    final _border = InputBorder.none;

    return Container(
      width: _deviceWidth! * 0.5,
      height: _deviceHeight! * 0.05,
      child: TextField(
        controller: _searchTextFieldController,
        onSubmitted: (_input) {},
        style: const TextStyle(
          color: Colors.white,
        ),
        decoration: InputDecoration(
          focusedBorder: _border,
          border: _border,
          prefixIcon: const Icon(
            Icons.search,
            color: Colors.white24,
          ),
          hintText: "Search....",
          hintStyle: const TextStyle(
            color: Colors.white54,
          ),
        ),
      ),
    );
  }

  Widget _categorySelectionWidget() {
    return DropdownButton<String>(
      dropdownColor: Colors.black38,
      value: SearchCategory.popular,
      icon: const Icon(
        Icons.menu,
        color: Colors.white24,
      ),
      items: [
        DropdownMenuItem(
          child: Text(
            SearchCategory.popular,
            style: const TextStyle(
              color: Colors.white,
            ),
          ),
          value: SearchCategory.popular,
        ),
        DropdownMenuItem(
          child: Text(
            SearchCategory.upcoming,
            style: const TextStyle(
              color: Colors.white,
            ),
          ),
          value: SearchCategory.upcoming,
        ),
        DropdownMenuItem(
          child: Text(
            SearchCategory.none,
            style: const TextStyle(
              color: Colors.white,
            ),
          ),
          value: SearchCategory.none,
        ),
      ],
      underline: Container(
        height: 1,
        color: Colors.white24,
      ),
      onChanged: (_value) {},
    );
  }

  Widget? _moviesListViewWidget() {
    final List<Movie> _movies = [];

    for (var i = 0; i < 10; i++) {
      _movies.add(
        Movie(
          name: "Movie 1",
          language: "EN",
          isAdult: false,
          description: "Nothing for now",
          rating: 8.0,
          releaseDate: "2021-10-20",
          posterPath: "/xGUOF1T3WmPSACQEQJfnG7Ud9f8.jpg",
          backdropPath: "/9yBVqNruk6Ykrwc32qrk2TIE5xw.jpg",
        ),
      );
    }

    if (_movies.isNotEmpty) {
      return ListView.builder(
        itemCount: _movies.length,
        itemBuilder: (BuildContext _context, int _index) {
          return Padding(
            padding: EdgeInsets.symmetric(
                vertical: _deviceHeight! * 0.01, horizontal: 0),
            child: GestureDetector(
              onTap: () {},
              child: MovieTile(
                movie: _movies[_index],
                height: _deviceHeight! * 0.2,
                width: _deviceWidth! * 0.85,
              ),
            ),
          );
        },
      );
    } else {
      return const Center(
        child: CircularProgressIndicator(
          backgroundColor: Colors.white,
        ),
      );
    }
  }
}

Here is the MainPageDataController class, I declared the state parameter as optional, and I am fetchinf movies in the getMovies function –

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:movie_app/model/main_page_data.dart';
import 'package:movie_app/model/movie.dart';
import 'package:movie_app/services/movie_service.dart';
import 'package:riverpod/riverpod.dart';

class MainPageDataController extends StateNotifier<MainPageData> {
  MainPageDataController([MainPageData? state])
      : super(state ?? MainPageData.initial()) {
    getMovies();
  }

  final MovieService _movieService = GetIt.instance.get<MovieService>();

  Future<void> getMovies() async {
    try {
      List<Movie> _movies = [];
      _movies = await _movieService.getPopularMovies(page: state.page);
    } catch (e) {}
  }
}