Home > Blockchain >  Could not find the correct Provider<Movies> above this MyApp Widget
Could not find the correct Provider<Movies> above this MyApp Widget

Time:04-07

So, I'm using BLoC and Provider packages in one app. In my 'moviesprovider.dart' I am fetching some data from my API which returns a json, when app is opening first time. How can I get access to Provider.of(context) from main.dart in MultiProvider? Basically, I want to get access to the same instance of List movies, but don't know how.

The error I'm getting:


Error: Could not find the correct Provider above this MyApp Widget

This happens because you used a BuildContext that does not include the provider of your choice.


Code: Main.dart

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider.value(
          value: Movies(),
        ),
        Provider<SwipeBloc>(create: (_) {
          SwipeBloc()
            ..add(
              LoadMoviesEvent(
                movies: context.read<Movies>().movies,
              ),
            );
        }),
        ChangeNotifierProvider.value(
          value: User(),
        ),
        ChangeNotifierProvider.value(
          value: Auth(),
        ),
      ],
      child: ...
  }
}

movies_provider.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:movies_recomendations/constants.dart';
import 'package:http/http.dart' as http;

import './single_movie_provider.dart';

class Movies with ChangeNotifier {
  String plotText = "";

  List<Movie> _movies = [];

  List<Movie> get movies {
    return <Movie>[..._movies];
  }

  .....

  Future<void> fetchAndSetMovies() async {
    const url = 'http://192.168.1.142:8000/Desktop/textData.json';

    try {
      final response = await http.get(
        Uri.parse(url),
      );
      String source = Utf8Decoder().convert(response.bodyBytes);

      final extractedData =
          List<Map<String, dynamic>>.from(json.decode(source));
      final List<Movie> loadedMovies = [];

      extractedData.forEach(
        ((movieInfo) => {
              loadedMovies.add(Movie(
                id: movieInfo['id'],
                age: 12,
                countries: List<String>.from(movieInfo['country']),
                description: movieInfo['descriprion'],
                frames: movieInfo['frames'],
                genre: movieInfo['genre'],
                poster: movieInfo['poster'],
                premiereWorld: movieInfo['date'].toString(),
                ratingIMDb: movieInfo['ratingIMDb'],
                ratingKinopoisk: movieInfo['ratingKinopoisk'],
                title: movieInfo['title'][1],
                ifSeries: movieInfo['ifSeries'],
                dateTo: movieInfo['dateTo'].toString(),
                isFavourite: true,
                seasons: movieInfo['seasons'],
              )),
            }),
      );
      _movies = loadedMovies;
      notifyListeners();
    } on Exception catch (e) {
      print('error');
      print(e.toString());
    }
  }
}

Swipe_event.dart

part of 'swipe_block.dart';

abstract class SwipeEvent extends Equatable {
  const SwipeEvent();

  @override
  List<Object> get props => [];
}

class LoadMoviesEvent extends SwipeEvent {
  final List<Movie> movies ;

  LoadMoviesEvent({
    required this.movies,
  });

  @override
  List<Object> get props => [movies];
}

class SwipeLeftEvent extends SwipeEvent {
  final Movie movie;

  SwipeLeftEvent({
    required this.movie,
  });

  @override
  List<Object> get props => [movie];
}

class SwipeRightEvent extends SwipeEvent {
  final Movie movie;

  SwipeRightEvent({
    required this.movie,
  });

  @override
  List<Object> get props => [movie];
}

CodePudding user response:

You probably need to move the code calling Provider.of(context) into its own widget. As the error implies you can't use Provider to retrieve dependencies within the same BuildContext you used to set the Provider scope. Creating a new widget will also generate a new BuildContext.

If you really need to use Provider.of(context) in the same class you define MultiProvider you could use the Builder widget to generate a new context.

CodePudding user response:

So, to solve this problem you should NOT use BlocProvider in main.dart. You should use it in that direct widget where BLoC Provider will be implemented. So I use it in one screen - recomendations, so I write it there like this

class RecomendationsScreen extends StatelessWidget {
  static const routeName = '/recomendations';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: kBackgroundColor,
      body: BlocProvider(
        create: (_) => SwipeBloc()
          ..add(
            LoadMoviesEvent(
              movies: Provider.of<Movies>(context).movies,
            ),
          ),
        child: RecomendationsBody(),
      ),
    );
  }
}

  • Related