The dart code I compile is:
import 'dart:js';
import 'package:dio/dio.dart';
final Dio _dio = Dio();
class LoginResponse extends GenericResponse {
String? accessToken;
String? refreshToken;
LoginResponse(statusCode, this.accessToken, this.refreshToken)
: super(statusCode);
}
Future<LoginResponse> login(String phoneNumber, String password, String otp) async {
Response response = await _dio.post(
"https://example.com/token/obtain/",
data: {'phone_number': phoneNumber, 'password': password, 'otp': otp},
options: Options(validateStatus: (status) => status! < 500),
);
return LoginResponse(response.statusCode, response.data['access'], response.data['refresh']);
}
main() => context['loginFromDart'] = login;
I wish to access LoginResponse.accessToken
and LoginResponse.refreshToken
from the browser console. But still didn't find a way to do it.
You're looking for the dart:js
library.
You need to basically use allowInterop
and the @JS()
notation.
The Promise
class
You define a custom Promise
class using the @JS
annotation. This is necessary to create a promise instance that can be used from JavaScript to interact with Dart asynchronous code:
@JS('Promise')
class Promise<T> {
external Promise(void executor(void resolve(T result), Function reject));
external Promise then(void onFulfilled(T result), [Function onRejected]);
}
For your example - LoginClass
class LoginResponse {
int userId;
int id;
LoginResponse(this.userId, this.id);
}
Dio and request setup
final _dio = Dio();
Future<LoginResponse> login() async {
// _dio.get("URL")
return LoginResponse(
response.data['userId'],
response.data['id'],
);
}
Perform login
The performLogin
function wraps the login process in a promise, allowing it to be accessed from JavaScript:
Promise performLogin() {
return Promise(js.allowInterop((resolve, reject) {
login().then((value) {
final jsonMap = {
'userId': value.userId,
'id': value.id,
};
final jsonString = jsonEncode(jsonMap);
resolve(jsonString);
}).catchError((error) {
reject(error);
});
}));
}
Binding performLogin
to Javascript Window
Object:
You use the setProperty
function from the js_util
library to bind the performLogin
function to the window
object. This makes it accessible from the browser console:
void main() {
setProperty(window, 'performLogin', js.allowInterop(performLogin));
}
You can now use:
performLogin().then(result => {
// You need to convert the result to JSON
const userData = JSON.parse(result);
console.log('userId: ', userData.userId);
console.log("ID: ", userData.id);
});
Result
Here's the complete code as a runnable snippet
import 'dart:html';
import 'dart:js' as js;
import 'dart:js_interop';
import 'package:js/js_util.dart';
import 'package:dio/dio.dart';
import 'dart:convert';
@JS('Promise')
class Promise<T> {
external Promise(void executor(void resolve(T result), Function reject));
external Promise then(void onFulfilled(T result), [Function onRejected]);
}
class LoginResponse {
int userId;
int id;
LoginResponse(this.userId, this.id);
}
final _dio = Dio();
Future<LoginResponse> login() async {
Response response = await _dio.get(
"https://jsonplaceholder.typicode.com/posts/1",
options: Options(validateStatus: (status) => status! < 500),
);
return LoginResponse(
response.data['userId'],
response.data['id'],
);
}
Promise performLogin() {
return Promise(js.allowInterop((resolve, reject) {
login().then((value) {
final jsonMap = {
'userId': value.userId,
'id': value.id,
};
final jsonString = jsonEncode(jsonMap);
resolve(jsonString);
}).catchError((error) {
reject(error);
});
}));
}
void main() {
setProperty(window, 'performLogin', js.allowInterop(performLogin));
}