I have this error;
Could there be a problem with the token.It says Uri invalid token, but I login beforehand, why can't I read it? Headers I add token like this..But it isnt work how solve it ? What could I have done wrong?
And So map, ifwhere, where or other things dont work..
I'm new to this platform, I may have asked something very simple, sorry for that.
Thank you for all ....
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_knowin_app/core/data/response.dart';
import 'package:flutter_knowin_app/core/util/constants.dart';
import 'package:flutter_knowin_app/features/promotions/domain/entities/check.dart';
import 'package:flutter_knowin_app/features/promotions/domain/entities/spin.dart';
import 'package:flutter_knowin_app/features/promotions/domain/repositories/spin_repository.dart';
import 'package:flutter_knowin_app/features/promotions/domain/usecases/check_regular.dart';
import 'package:flutter_knowin_app/features/promotions/domain/usecases/check_vip.dart';
import 'package:flutter_knowin_app/injection_container.dart';
part 'spin_event.dart';
part 'spin_state.dart';
enum SpinPageState {
regular,
vip,
}
class SpinBloc extends Bloc<SpinEvent, SpinState> {
final SpinRepository spinRepository = sl<SpinRepository>();
SpinPageState spinPageState;
bool stateVip;
bool spinState = false;
String winThing;
int winResult;
int gamePlayCountVip;
int gamePlayCountRegular;
checksRegular ChecksRegular;
checksVip ChecksVip;
SpinBloc({
#required checksRegular ChecksRegular,
#required checksVip ChecksVip,
})
: assert(checksRegular != null),
assert(checksVip != null),
ChecksRegular = ChecksRegular,
ChecksVip = ChecksVip,
super(SpinState.initial());
#override
Stream<SpinState> mapEventToState(SpinEvent event,) async* {
final SpinRepository spinRepository = sl<SpinRepository>();
SpinState.initial();
if (event is SpinLoadingEvent) {
Response updateResponse;
yield SpinLoadingState();
final checkRegularOrFailure = await ChecksRegular(
checksRegularParams());
final checkVipOrFailure = await ChecksVip(
checksVipParams());
checkRegularOrFailure.fold((failure) {
updateResponse = Response(
status: false,
message: UNEXPECTED_FAILURE_MESSAGE,
statusCode: "FAIL CHECK REGULAR",
);
}, (response) {
spinState = true;
spinPageState = SpinPageState.regular;
response.toList().where((e){
print("PEOPLE COUNT= ${ e.gamePlayed}");
});
});
checkVipOrFailure.fold((failure) {
updateResponse = Response(
status: false,
message: UNEXPECTED_FAILURE_MESSAGE,
statusCode: "FAIL CHECK VIP",
);
}, (response) {
spinState = true;
spinPageState = SpinPageState.vip;
});
yield SpinLoadingState();
}
if (event is SpinStartEvent) {
}
}
}
RemoteCode;
class PromotionRemoteDataSourceImpl implements PromotionRemoteDataSource {
String token;
final http.Client client;
PromotionRemoteDataSourceImpl({this.client});
Map<String, String> get defaultHeaders =>
{
'Accept': 'application/json',
'Authorization': 'Bearer $token',
"Content-Type": "application/json"
};
Map<String, String> get defaultQueryParams => {
"lang": Platform.localeName.split('_')[0],
};
#override
Future<List<Check>> checksRegular() async {
Uri uri = Uri.https(
API_URL,
'/promotions/check/regular',
defaultQueryParams,
);
print("URİ: "+ uri.toString());
final response = await client.get(uri, headers: defaultHeaders);
final body= json.decode(response.body);
I solved the error like this;
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
sl<PromotionRemoteDataSource>().token = userState.token;//!!!
});
}
I think the problem is here
response.toList().where((e){
print("PEOPLE COUNT= ${ e.gamePlayed}");
});
The reason why is as the error message stated. The response variable is null, and you're trying to convert null to a list and Dart didn't like that. Implement some way to deal with the scenario where response is null, e.g. have an if statement there, and that should hopefully solve your problem
Related
I'm writing a Unit test for my data source and face the problem No stub was found which matches the arguments of this method call
import 'dart:convert';
import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:true_food/core/constant.dart';
import 'package:true_food/core/network_manager.dart';
import 'package:true_food/features/home/data/datasources/home_data_source.dart';
import 'package:true_food/features/home/data/models/shelve.dart';
import 'package:true_food/features/home/data/models/shelve_banner_list.dart';
import 'package:true_food/features/home/domain/entities/banner_list_request_model.dart';
import '../../../../core/utils/fixture_reader.dart';
import 'home_data_source_test.mocks.dart';
#GenerateMocks([NetworkManager])
main() {
late HomeDataSourceImpl dataSource;
late MockNetworkManager mockNetworkManager;
final successCode = 201;
final shelveUrl = Constant.baseUrl + APIRoute.shelveList;
final bannerUrl = Constant.baseUrl + APIRoute.bannerList;
setUp(() {
mockNetworkManager = MockNetworkManager();
dataSource = HomeDataSourceImpl(mockNetworkManager);
});
void onCallSuccess(Function body) {
group('Get list successfully', () {
body();
});
}
void onCallFailed(Function body) {
group('Get list unsuccessfully', () {
body();
});
}
BannerListRequestModel request = const BannerListRequestModel(
url:
"/weshop/api/TRUEID_TRUEFOOD/shelfContent?type=item&sort=sequence&itemGroup=6183b134b6d93f000180bf76&page={sys.page}&size={sys.size}&publishStatus=true",
location: BannerListRequestLocationModel(latitude: 0.0, longitude: 0.0),
page: 0,
size: 4);
Future<void> makeResponseSuccessfull(dynamic data) async {
final Response response =
Response(requestOptions: RequestOptions(path: 'path'), statusCode: 200);
when(mockNetworkManager.request(
path: shelveUrl,
method: Method.get,
param: {
"publishOnApp": true,
},
headers: null,
isFormData: false,
contentType: 'application/json',
isFullPath: false,
language: "th",
date: null,
file: null,
check: false,
)).thenAnswer((_) async => Right(response));
}
void makeBannerListResponseSuccessfull(dynamic data) async {
final Response response = Response(
requestOptions: RequestOptions(path: 'path'),
statusCode: 200,
data: data);
when(mockNetworkManager.request(
path: bannerUrl,
method: Method.post,
param: request.toMap(),
headers: null,
isFormData: false,
contentType: 'application/json',
isFullPath: false,
language: "th",
date: null,
file: null,
check: false,
)).thenAnswer((_) async => Right(response));
}
onCallSuccess(() {
test('should perform GET for get shelve list successfully', () async {
final json = jsonDecode(fixture("shelve_list_data.json"));
final List<ShelveModel> list =
List<ShelveModel>.from(json.map((e) => ShelveModel.fromJson(e)));
// arrange
await makeResponseSuccessfull(json);
// act
final rs = await dataSource.getList(publishOnApp: true);
// assert
expect(rs, list);
});
test('should perform POST for get banner list successfully', () async {
final json = jsonDecode(fixture("banner_list_data.json"));
final List<ShelveBannerListModel> list = List<ShelveBannerListModel>.from(
json.map((e) => ShelveBannerListModel.fromJson(e)));
// arrange
makeBannerListResponseSuccessfull(json);
// act
final rs = await dataSource.getBannerList(request: request);
// assert
expect(rs, list);
});
});
}
My NetworkManager class:
import 'dart:convert';
import 'dart:io';
import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:flutter_flavor/flutter_flavor.dart';
import 'package:injectable/injectable.dart';
import 'package:true_food/core/constant.dart';
import 'package:true_food/core/error/error.dart';
import 'package:true_food/core/error/exceptions.dart';
import 'package:true_food/core/local_storage.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:true_food/gen/locale_keys.g.dart';
import 'package:dio/adapter.dart';
#lazySingleton
class NetworkManager {
final dio = Dio();
Future<Either<ServerException, Response>> request({
required String path,
required Method method,
Map<String, dynamic>? param,
Map<String, dynamic>? headers,
bool isFormData = false,
String contentType = 'application/json',
bool isFullPath = false,
String language = 'vi',
// ignore: avoid_init_to_null
DateTime? date = null,
// ignore: avoid_init_to_null
FormData? file = null,
bool check = false,
}) async {
final String? _token = LocalStorage().getString(Constant.accessToken);
print('_token: $_token');
String domain = FlavorConfig.instance.variables["baseUrl"] ?? '';
String _finalPath = domain + path;
Map<String, dynamic> _finalParam = {};
if (param != null) {
print(param);
_finalParam.addAll(param);
}
try {
Map<String, dynamic>? _header =
_token != null ? {"Authorization": "Bearer " + _token} : null;
Response response = Response(requestOptions: RequestOptions(path: path));
Options optionsCommon = Options(
headers: _header,
sendTimeout: 30 * 1000,
receiveTimeout: 30 * 1000,
contentType: contentType,
);
//handle old printic with the request without content type
switch (method) {
case Method.get:
response = await dio.get(
_finalPath,
queryParameters: _finalParam,
options: optionsCommon,
cancelToken: null,
onReceiveProgress: null,
);
break;
case Method.post:
var data = isFormData ? file : _finalParam;
response = await dio.post(
_finalPath,
options: optionsCommon,
data: data,
cancelToken: null,
onReceiveProgress: null,
);
break;
case Method.put:
var data = isFormData ? file : _finalParam;
response = await dio.put(
_finalPath,
options: optionsCommon,
data: data,
cancelToken: null,
onReceiveProgress: null,
);
break;
case Method.delete:
var data = isFormData ? file : _finalParam;
response = await dio.delete(
_finalPath,
options: optionsCommon,
data: data,
cancelToken: null,
);
break;
}
print('==> DIO SUCCESS <$path> RESPONSE :\n'
'${response.data}');
// onSuccess(response.data, response.statusCode ?? 200);
return Right(response);
} on DioError catch (e) {
if (e.response != null) {
final Response rp = e.response!;
if (rp.statusCode == 502) {
// showToast("Server is maintaining, please login later".tr());
// UserManager.instance.logout();
// EasyLoading.dismiss();
}
print('~~> e: ${e.error}');
print('==> DIO FAILED <$path> RESPONSE :\n'
'${e.response?.data ?? ""}');
final data = rp.data;
try {
final json = jsonDecode(data);
return Left(ServerException(appError: AppError.fromJson(json)));
} on Exception {
return Left(ServerException(
appError: AppError(
status: 500,
title: LocaleKeys.something_went_wrong.tr(),
message: LocaleKeys.something_went_wrong.tr())));
}
} else {
return Left(ServerException(
appError: AppError(
status: 500,
title: LocaleKeys.something_went_wrong.tr(),
message: LocaleKeys.something_went_wrong.tr(),
),
));
}
} on SocketException {
return Left(ServerException(
appError: AppError(
status: 500,
title: LocaleKeys.something_went_wrong.tr(),
message: LocaleKeys.something_went_wrong.tr())));
}
}
}
enum Method { post, get, put, delete }
Pubspec:
Mockito version: "5.1.0"
Dio version "4.0.5"
MissingStubError: 'request'
No stub was found which matches the arguments of this method call:
request({path: api/shelves, method: Method.get, param: {publishOnApp: true}, headers: null, isFormData: false, contentType: application/json, isFullPath: false, language: vi, date: null, file: null, check: false})
Add a stub for this method using Mockito's 'when' API, or generate the MockNetworkManager mock with a MockSpec with 'returnNullOnMissingStub: true' (see https://pub.dev/documentation/mockito/latest/annotations/MockSpec-class.html).
I am trying to use mockito to return a fake response in the http.Client call and be able to test the service. I have followed the documentation. It tells me that I should use annotate to generate a fake class, but it seems that the null safe of flutter is causing problems. Does anyone know how? fix it thanks
movies_provider_test.dart
import 'package:http/http.dart' as http;
import 'package:mockito/mockito.dart';
import 'package:mockito/annotations.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:watch_movie_app/src/data/data_source/remote/http_request.dart';
import 'package:watch_movie_app/src/data/models/models.dart';
import 'package:watch_movie_app/src/domain/services/movie_service.dart';
import 'package:watch_movie_app/src/environment_config.dart';
import 'mocks/popular_movies.dart';
import 'movies_provider_test.mocks.dart';
#GenerateMocks([http.Client])
void main() {
test('returns an movies if the http call completes sucessfully', () async {
final mockHttp = MockClient();
final container = ProviderContainer(
overrides: [
httpClientProvider.overrideWithValue(HttpRequest(httpClient: mockHttp)),
],
);
addTearDown(container.dispose);
final environmentConfig = container.read(environmentConfigProvider);
final movieService = container.read(movieServiceProvider);
String urlApi =
"${environmentConfig.domainApi}/${environmentConfig.apiVersion}/tv/popular?api_key=${environmentConfig.movieApiKey}&language=en-US&page=1";
Uri url = Uri.parse(urlApi);
when(mockHttp.get(url)).thenAnswer(
(_) async => http.Response(fakeMovies, 200),
);
expectLater(await movieService.getMovies(), isInstanceOf<List<Movie>>());
});
}
movie_service.dart
import 'package:http/http.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:watch_movie_app/src/data/data_source/remote/http_request.dart';
import 'package:watch_movie_app/src/domain/enums/enums.dart';
import 'package:watch_movie_app/src/data/models/models.dart';
import 'package:watch_movie_app/src/environment_config.dart';
import 'package:watch_movie_app/src/helpers/movie_api_exception.dart';
final movieServiceProvider = Provider<MovieService>((ref) {
final config = ref.read(environmentConfigProvider);
final httpRequest = ref.read(httpClientProvider);
return MovieService(config, httpRequest);
});
class MovieService {
final EnvironmentConfig _environmentConfig;
final HttpRequest _http;
MovieService(this._environmentConfig, this._http);
Future<List<Movie>> getMovies() async {
try {
String url =
"${_environmentConfig.domainApi}/${_environmentConfig.apiVersion}/tv/popular?api_key=${_environmentConfig.movieApiKey}&language=en-US&page=1";
final response =
await _http.request(typeHttp: EnumHttpType.get, urlApi: url);
if (response.statusCode != 200) {
throw const MovieApiException('Error al consulta las series populares');
}
List<Movie> movies = allMoviesFromJson(response.body);
return movies;
} on ClientException {
throw const MovieApiException('Error al consultar la información');
}
}
Future<List<Movie>> getMoviesRecommendations() async {
try {
String url =
"${_environmentConfig.domainApi}/${_environmentConfig.apiVersion}/tv/top_rated?api_key=${_environmentConfig.movieApiKey}&language=en-US&page=1";
final response =
await _http.request(typeHttp: EnumHttpType.get, urlApi: url);
if (response.statusCode != 200) {
throw const MovieApiException(
'Error al consulta las series recomendadas');
}
List<Movie> movies = allMoviesFromJson(response.body);
return movies;
} on ClientException {
throw const MovieApiException('Error al consultar los recomendados');
}
}
Future<MovieExtend> getDetailMovie(int id) async {
try {
String url =
"${_environmentConfig.domainApi}/${_environmentConfig.apiVersion}/tv/$id?api_key=${_environmentConfig.movieApiKey}&language=en-US&page=1";
final Response response =
await _http.request(typeHttp: EnumHttpType.get, urlApi: url);
if (response.statusCode != 200) {
throw const MovieApiException(
'Error al consulta el detalle de la serie');
}
MovieExtend movieExtend = movieExtendFromJson(response.body);
return movieExtend;
} on ClientException {
throw const MovieApiException(
'Error al consultar el detalle de la serie');
}
}
Future<List<Movie>> getAirtodayMovies() async {
try {
String url =
"${_environmentConfig.domainApi}/${_environmentConfig.apiVersion}/tv/airing_today?api_key=${_environmentConfig.movieApiKey}&language=en-US&page=1";
final Response response =
await _http.request(typeHttp: EnumHttpType.get, urlApi: url);
if (response.statusCode != 200) {
throw const MovieApiException(
'Error al consultar las series, intente nuevamente mas tarde');
}
List<Movie> movies = allMoviesFromJson(response.body);
return movies;
} on ClientException {
throw const MovieApiException('Error al consultar las series de hoy');
}
}
}
htt_request.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http;
import 'package:watch_movie_app/src/domain/enums/enums.dart';
/// Clase que nos permite hacer peticiones Http
/// usando la libreria http.dar
class HttpRequest {
final http.Client _httpClient;
late String? token;
HttpRequest({http.Client? httpClient})
: _httpClient = httpClient ?? http.Client();
Future<http.Response> request(
{required EnumHttpType typeHttp, required String urlApi, data}) async {
Map<String, String> headers = {'Content-Type': 'application/json'};
Uri url = Uri.parse(urlApi);
switch (typeHttp) {
case EnumHttpType.post:
return _httpClient.post(url, body: data, headers: headers);
case EnumHttpType.get:
return _httpClient.get(url, headers: headers);
case EnumHttpType.patch:
return _httpClient.patch(url, headers: headers);
case EnumHttpType.put:
return _httpClient.put(url, headers: headers);
case EnumHttpType.delete:
return _httpClient.delete(url, headers: headers);
default:
return _httpClient.get(url);
}
}
}
final httpClientProvider = Provider<HttpRequest>((ref) => HttpRequest());
error detail
MissingStubError: 'get'
No stub was found which matches the arguments of this method call:
get(https://api.themoviedb.org/3/tv/popular?api_key=4dc138c853e44e4ea1d3dfd746fe451d&language=en-US&page=1, {headers: {Content-Type: application/json}}\)
Add a stub for this method using Mockito's 'when' API, or generate the MockClient mock with a MockSpec with 'returnNullOnMissingStub: true' (see https://pub.dev/documentation/mockito/latest/annotations/MockSpec-class.html\).
package:mockito/src/mock.dart 191:7 Mock._noSuchMethod
package:mockito/src/mock.dart 185:45 Mock.noSuchMethod
test\movies_provider_test.mocks.dart 45:14 MockClient.get
package:watch_movie_app/src/data/data_source/remote/http_request.dart 23:28 HttpRequest.request
package:watch_movie_app/src/domain/services/movie_service.dart 26:23 MovieService.getMovies
test\movies_provider_test.dart 36:36 main.<fn>
test\movies_provider_test.dart 17:68
link doc:
mockito unit testing
Manually mocking http.Client is tricky. Stubs must match arguments exactly. In your case, you created a stub for:
when(mockHttp.get(url)).thenAnswer(...);
but the error indicates what was actually called:
No stub was found which matches the arguments of this method call:
get(<Long URL omitted>, {headers: {Content-Type: application/json}}\)
Your stub is not registered for a call that supplies a headers argument.
You really should avoid trying to create a manual mock for http.Client and instead use the MockClient class explicitly provided by package:http. It's much easier to use.
Indeed, as my colleague #jamesdlin commented, the solution was to use the MockClient class, below I share the implementation working correctly in case someone goes through this, thank you very much jamesdlin
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:watch_movie_app/src/data/data_source/remote/http_request.dart';
import 'package:watch_movie_app/src/data/models/models.dart';
import 'package:watch_movie_app/src/domain/services/movie_service.dart';
import 'mocks/popular_movies.dart';
void main() {
test('returns an instance of movies if the http call completed sucessfully',
() async {
final mockHttp = MockClient((_) async => http.Response(fakeMovies, 200));
final container = ProviderContainer(
overrides: [
httpClientProvider.overrideWithValue(HttpRequest(httpClient: mockHttp)),
],
);
addTearDown(container.dispose);
final movieService = container.read(movieServiceProvider);
expectLater(await movieService.getMovies(), isInstanceOf<List<Movie>>());
});
}
How to retrieve a new token with a refresh token in flutter in a ferry (graphql) client?
The response after a mutation looks like this:
{
"data": {
"auth_login": {
"access_token": "ey...",
"refresh_token": "Ua...",
"expires": 900000
}
}
}
I tried to accomplish it with fresh_graphql, but it does not work. The authenticationStatus is always unauthenticated but the token was always legit.
Implementation:
import 'dart:math';
import 'package:ferry/ferry.dart';
import 'package:ferry_hive_store/ferry_hive_store.dart';
import 'package:fresh_graphql/fresh_graphql.dart';
import 'package:gql_http_link/gql_http_link.dart';
import 'package:hive/hive.dart';
Future<Client> initClient(String? accessToken, String? refreshToken) async {
Hive.init('hive_data');
final box = await Hive.openBox<Map<String, dynamic>>('graphql');
await box.clear();
final store = HiveStore(box);
final cache = Cache(store: store);
final freshLink = await setFreshLink(accessToken ?? '', refreshToken);
final link = Link.from(
[freshLink, HttpLink('https://.../graphql/')]);
final client = Client(
link: link,
cache: cache,
);
return client;
}
Future<FreshLink> setFreshLink(String accessToken, String? refreshToken) async {
final freshLink = FreshLink<dynamic>(
tokenStorage: InMemoryTokenStorage<dynamic>(),
refreshToken: (dynamic token, client) async {
print('refreshing token!');
await Future<void>.delayed(const Duration(seconds: 1));
if (Random().nextInt(1) == 0) {
throw RevokeTokenException();
}
return OAuth2Token(
accessToken: 'top_secret_refreshed',
);
},
shouldRefresh: (_) => Random().nextInt(2) == 0,
)..authenticationStatus.listen(print);
print(freshLink.token);
print(freshLink.authenticationStatus);
await freshLink
.setToken(OAuth2Token(tokenType: 'Bearer', accessToken: accessToken));
return freshLink;
}
Any solution, even without fresh_graphql, would be appreciated!
The way I initialize my ferry client is as follows.
Create a CustomAuthLink that inherits from AuthLink.
import 'package:gql_http_link/gql_http_link.dart';
class _CustomAuthLink extends AuthLink {
_CustomAuthLink() : super(
getToken: () {
// ...
// Call your api to refresh the token and return it
// ...
String token = await ... // api refresh call
return "Bearer $token"
}
);
}
Use this custom auth link to initialise your client.
...
final link = Link.from([freshLink, HttpLink('https://.../graphql/')]);
...
Client(
link: _CustomAuthLink().concat(link),
)
...
I am not sure if you still going to need freshLink anymore. You might wanna remove it and pass HttpLink(...) directly into the .concat(...) method.
I'm new to programming in general and very new to flutter, I get this following error message on both the "body" and "header" in the code which is marked in bold. I have tried everything I could find online for any help, but now found any solution, I figure this probobly isn't the hardest thing for someone who knows programming to solve, but I'm a beginner so I would really like the help. Thanks in advance.
import 'dart:convert';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'model.dart';
const API_URL = 'https://todoapp-api-pyq5q.ondigitalocean.app';
const API_KEY = '7037674e-2262-4502-a2e1-29c940bd2a7a';
class Api {
static Future addTodoModel(TodoModel todo) async {
var json = todo.toJson();
var bodyString = jsonEncode(json);
var response = await http.post(Uri.parse('$API_URL/todos?key=$API_KEY',
**body: bodyString, headers:** {'Content-Type': 'application/json'}));
if (response.statusCode == 200) {
return response;
} else {
print('error on add');
return null;
}
}
static Future updateTodo(TodoModel todo, todoId) async {
var json = todo.toJson();
var bodyString = jsonEncode(json);
var response = await http.put(Uri.parse('$API_URL/todos/$todoId?key=$API_KEY',
**body: bodyString, headers:** {'Content-Type': 'application/json'}));
if (response.statusCode == 200) {
return response;
} else {
print('error on update');
return null;
}
}
static Future removeTodoModel(String todoId) async {
try {
var response = await http.delete(Uri.parse('$API_URL/todos/$todoId?key=$API_KEY'));
if (response.statusCode == 200) {
return response;
}
print('exception on remove');
} catch (exception) {
throw exception;
}
}
static Future<List<TodoModel>> getTodoModel() async {
try {
var response = await http.get(Uri.parse('$API_URL/todos?key=$API_KEY'));
var json = jsonDecode(response.body);
return json.map<TodoModel>((data) {
return TodoModel.fromJson(data);
}).toList();
} catch (exception) {
throw exception;
}
}
}
The Uri.parse funtion has no "header" or "body" parameter.
"headers" and "body" should be post method's params, like this:
Body and Headers are available in method of http.
For example:
import 'package:http/http.dart' as http;
// POST method
final response = await http.post(
url,
headers: {}, // Map<String*, String*>* headers
body: json.encode(params), // params is Map<String, dynamic>
);
right now i have a ChangeNotifierProvider, and i want to set some values straight in the initState method.
those values come from a backend API, that are retrieved in that provider.
I am stuck is this situation for a while now, hope i can get some help.
Here is the ChangeNotifierProvider
final userProvider = ChangeNotifierProvider.autoDispose.family<UserProxy, String>((ref, id) {
var notifier = UserProxy(userId: id);
notifier.load();
return notifier;
});
class UserProxy extends ChangeNotifier {
String userId;
User? user;
UserProxy({this.userId = ""});
void load() async {
await getUser().then((value) => generateObject(value));
}
Future<String> getUser() async {
Map<String, String> queryParams = {
"id": userId,
};
var url = Uri.https("asdadas.asdasd.com", "endpoint", queryParams);
Map<String, String> headers = {
'content-type': "application/json",
};
var response = await http.get(url,
headers: headers,);
print(response.body);
return response.body;
}
User generateObject(String jsonString) {
this.user = User.fromJson(jsonDecode(jsonString));
notifyListeners();
return this.user ?? User();
}
}
For this case I would suggest
FutureProvider.autoDispose.family<UserProxy, String>((ref, id) async { .... })
then change your StateWidget to ConsumerStatefulWidget and ConsumerState<>
then
ref.watch(provider(11)).when(
loading: (){},
error: (Object err, StackTrace? st){ },
data: (user){
// build widget with result here.
},
)