buat file model dari response api, disini saya menggunakan web https://app.quicktype.io/ untuk membuat file modelnya, gunakan aplikasi postman untuk melihat model response yang diterima dari API.
kemudian copy dan paste ke web https://app.quicktype.io/. copas codingan dart yang telah digenerate ke dalam file model yang dibuat di dalam folder *********************data/models/*********************
// To parse this JSON data, do
//
// final renewTokenResponseModel = renewTokenResponseModelFromJson(jsonString);
import 'dart:convert';
RenewTokenResponseModel renewTokenResponseModelFromJson(String str) =>
RenewTokenResponseModel.fromJson(json.decode(str));
String renewTokenResponseModelToJson(RenewTokenResponseModel data) =>
json.encode(data.toJson());
class RenewTokenResponseModel {
bool? status;
String? message;
Data? data;
dynamic err;
RenewTokenResponseModel({
this.status,
this.message,
this.data,
this.err,
});
factory RenewTokenResponseModel.fromJson(Map<String, dynamic> json) =>
RenewTokenResponseModel(
status: json["status"],
message: json["message"],
data: json["data"] == null ? null : Data.fromJson(json["data"]),
err: json["err"] == [] ? [] : Err.fromJson(json["err"]),
);
Map<String, dynamic> toJson() => {
"status": status,
"message": message,
"data": data?.toJson(),
"err": err == null ? [] : List<dynamic>.from(err!.map((x) => x)),
};
}
class Data {
String? apiToken;
DateTime? apiExpired;
Data({
this.apiToken,
this.apiExpired,
});
factory Data.fromJson(Map<String, dynamic> json) => Data(
apiToken: json["api_token"],
apiExpired: json["api_expired"] == null
? null
: DateTime.parse(json["api_expired"]),
);
Map<String, dynamic> toJson() => {
"api_token": apiToken,
"api_expired": apiExpired?.toIso8601String(),
};
}
class Err {
String? error;
Err({
this.error,
});
factory Err.fromJson(Map<String, dynamic> json) => Err(
error: json["error"],
);
Map<String, dynamic> toJson() => {
"error": error,
};
}
membuat contract dari service yang akan digunakan
import 'package:core_mobile/src/config/const/data_state.const.dart';
import 'package:core_mobile/src/features/access_token/data/models/access_token_response.model.dart';
abstract class AccessTokenService {
Future<DataState<RenewTokenResponseModel>> renewAccessToken({
required String email,
required String token,
}) =>
throw UnimplementedError();
}
kemudian membuat implementasi dari service untuk post method
import 'dart:convert';
import 'dart:io';
import 'package:core_mobile/src/config/const/data_state.const.dart';
import 'package:core_mobile/src/config/const/endpoint.const.dart';
import 'package:core_mobile/src/config/const/parameter.const.dart';
import 'package:core_mobile/src/features/access_token/data/data_sources/remote/access_token.service.dart';
import 'package:core_mobile/src/features/access_token/data/models/access_token_response.model.dart';
import 'package:http/http.dart' as http;
class AccessTokenServiceImpl implements AccessTokenService {
@override
Future<DataState<RenewTokenResponseModel>> renewAccessToken({
required String email,
required String token,
}) async {
try {
var url = Uri.parse(EndpointConst.authRenewTokenEndpoint);
var response = await http.post(
url,
body: {
ParameterConst.emailParameter: email,
ParameterConst.tokenParameter: token,
},
);
print("STATUS CODE : ${response.statusCode}");
var decodedResponse = jsonDecode(response.body);
RenewTokenResponseModel responseModel =
RenewTokenResponseModel.fromJson(decodedResponse);
if (response.statusCode == HttpStatus.ok) {
return DataSuccess(responseModel);
} else {
return DataFailed(Exception(
'${EndpointConst.authRenewTokenEndpoint} : ${response.statusCode}\n${responseModel.message}'));
}
} catch (e) {
return AplicationError(
Exception('${EndpointConst.authRenewTokenEndpoint}\n$e'));
}
}
}
selanjutnya membuat contract repository di folder domain
import 'package:core_mobile/src/config/const/data_state.const.dart';
import 'package:core_mobile/src/features/access_token/data/models/access_token_response.model.dart';
import 'package:core_mobile/src/features/access_token/data/models/local_token.model.dart';
class AccessTokenRepository {
Future<DataState<RenewTokenResponseModel>> renewAccessToken({
required String email,
required String token,
}) =>
throw UnimplementedError();
}
kemudian membuat implementasi dari repository yang telah dibuat
import 'package:core_mobile/src/config/const/data_state.const.dart';
import 'package:core_mobile/src/features/access_token/data/data_sources/local/local_access_token.service.dart';
import 'package:core_mobile/src/features/access_token/data/data_sources/local/local_access_token.service.impl.dart';
import 'package:core_mobile/src/features/access_token/data/data_sources/remote/access_token.service.dart';
import 'package:core_mobile/src/features/access_token/data/data_sources/remote/access_token.service.impl.dart';
import 'package:core_mobile/src/features/access_token/data/models/access_token_response.model.dart';
import 'package:core_mobile/src/features/access_token/data/models/local_token.model.dart';
import 'package:core_mobile/src/features/access_token/domain/repositories/access_token.repository.dart';
class AccessTokenRepositoryImpl implements AccessTokenRepository {
AccessTokenService accessTokenService = AccessTokenServiceImpl();
LocalAccessTokenService localAccessTokenService =
LocalAccessTokenServiceImpl();
@override
Future<DataState<RenewTokenResponseModel>> renewAccessToken(
{required String email, required String token}) {
return accessTokenService.renewAccessToken(email: email, token: token);
}
}
selanjutnya kita membuat use case dari post API
import 'package:core_mobile/src/config/const/data_state.const.dart';
import 'package:core_mobile/src/features/access_token/data/models/access_token_response.model.dart';
import 'package:core_mobile/src/features/access_token/data/models/local_token.model.dart';
import 'package:core_mobile/src/features/access_token/data/repositories/access_token.repository.impl.dart';
import 'package:core_mobile/src/features/access_token/domain/repositories/access_token.repository.dart';
class AccessTokenUseCase {
AccessTokenRepository accessTokenRepository = AccessTokenRepositoryImpl();
Future<DataState<RenewTokenResponseModel>> renewAccessToken({
required String email,
required String token,
}) {
return accessTokenRepository.renewAccessToken(email: email, token: token);
}
}
selanjutnya membuat viewmodels atau state management file
import 'package:core_mobile/src/commons/widgets/custom_dialog.widget.dart';
import 'package:core_mobile/src/commons/widgets/snackbar_message.widget.dart';
import 'package:core_mobile/src/config/const/data_state.const.dart';
import 'package:core_mobile/src/features/access_token/domain/use_cases/access_token.usecase.dart';
import 'package:core_mobile/src/features/auth/login/domain/use_cases/login.usecase.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
class AccessTokenViewmodel extends ChangeNotifier {
final ChangeNotifierProviderRef tokenRef;
AccessTokenViewmodel(this.tokenRef);
LoginUseCase loginUseCase = LoginUseCase();
AccessTokenUseCase accessTokenUseCase = AccessTokenUseCase();
Future<void> renewAccessToken({required BuildContext context}) async {
final loggedUser = loginUseCase.getLoggedUser();
final tokenData = accessTokenUseCase.getLocalAccessToken();
if (DateTime.now().isAfter(tokenData.apiExpired!)) {
final responseState = await accessTokenUseCase.renewAccessToken(
email: loggedUser.email!,
token: tokenData.apiToken!,
);
print('RESPONSE STATE : $responseState');
if (responseState is DataSuccess) {
accessTokenUseCase.updateLocalAccessToken(
apiExpired: responseState.data!.data!.apiExpired!,
token: responseState.data!.data!.apiToken!,
);
CustomSnackBarMessage.showSnackBarMessage(
context, responseState.data!.message!, 3);
} else if (responseState is DataFailed) {
CustomSnackBarMessage.showSnackBarMessage(
context, responseState.error.toString(), 2);
} else {
CustomDialogMessage.showDialogMessage(
context,
[],
Text(responseState.error.toString()),
'Error/Bugs',
FontAwesomeIcons.triangleExclamation,
);
}
}
}
}
acces token ini diperlukan sebagai header untuk menghit endpoint-endpoint selain auth. dalam contoh kasus diatas endpoint akan dihit apabila telah expire.