1

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. enter image description here

MendelG
  • 14,885
  • 4
  • 25
  • 52
Vassily
  • 5,263
  • 4
  • 33
  • 63

1 Answers1

1

You're looking for the dart:js library.

You need to basically use allowInterop and the @JS() notation.

Setup

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));
}

Calling the code within the Browser console

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

enter image description here

Putting it all together

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));
}

See also

MendelG
  • 14,885
  • 4
  • 25
  • 52