Flutter:type 'Null' is not a subtype of type 'String' in type cast

I’m getting the following error after building my flutter app after i run the flutter run:

type ‘Null’ is not a subtype of type ‘String’ in type cast

The trace that is observed is as follows :

I/flutter ( 8093): type 'Null' is not a subtype of type 'String' in type cast
I/flutter ( 8093): #0      new Future.value (dart:async/future.dart:349:59)
I/flutter ( 8093): #1      ProxySettings.findProxy (package:Myapp/plugins/proxy_settings.dart:14:21)
I/flutter ( 8093): #2      MyAppProviderState.initAsyncState (package:Myapp/provider.dart:215:39)
I/flutter ( 8093): <asynchronous suspension>
I/flutter ( 8093): In dev mode. Not sending report to Sentry.io.
I/flutter ( 8093): Clearing prompted user for permission


provider.dart

void initAsyncState() async {
    Environment environment =
        await EnvironmentLoader(environmentPath: ".env.json").load();
    httpService.setMagicHeader(
        environment.magicHeaderName, environment.magicHeaderValue);
    httpService
        .setProxy(await ProxySettings.findProxy(Uri.parse(environment.apiUrl))); --> Line 215 which is shown in the trace(provider.dart).
        
environment_loader.dart

import 'dart:async' show Future;
import 'dart:convert' show json;
import 'package:flutter/services.dart' show rootBundle;

class EnvironmentLoader {
  final String? environmentPath;

  EnvironmentLoader({this.environmentPath});

  Future<Environment> load() {
    return rootBundle.loadStructuredData<Environment>(this.environmentPath!,
        (jsonStr) async {
      final environmentLoader = Environment.fromJson(json.decode(jsonStr));
      return environmentLoader;
    });
  }
}

class Environment {
  final String apiUrl;
  final String magicHeaderName;
  final String magicHeaderValue;
  // final String intercomIosKey;
  // final String intercomAndroidKey;
  // final String intercomAppId;
  final String sentryDsn;
  final String myappapiurl;
  final String linkPreviewsTrustedProxyUrl;

  const Environment(
  {
    this.sentryDsn = '',
    this.myappapiurl = '',
    this.apiUrl = '',
    this.magicHeaderName = '',
    this.magicHeaderValue = '',
    // this.intercomAndroidKey = '',
    // this.intercomAppId = '',
    this.linkPreviewsTrustedProxyUrl = '',
    // this.intercomIosKey = ''
  });

  factory Environment.fromJson(Map<String, dynamic> jsonMap) {
    return new Environment(
      apiUrl: jsonMap["API_URL"],
      magicHeaderName: jsonMap["MAGIC_HEADER_NAME"],
      magicHeaderValue: jsonMap["MAGIC_HEADER_VALUE"],
      // intercomAppId: jsonMap["INTERCOM_APP_ID"],
      // intercomIosKey: jsonMap["INTERCOM_IOS_KEY"],
      // intercomAndroidKey: jsonMap["INTERCOM_ANDROID_KEY"],
      sentryDsn: jsonMap["SENTRY_DSN"],
      myappapiurl: jsonMap["KOSMOSNETWORK_SOCIAL_API_URL"],
      linkPreviewsTrustedProxyUrl: jsonMap["LINK_PREVIEWS_TRUSTED_PROXY_URL"],
    );
  }
}

.env.json

{
  "API_URL": "http://'mydomain':80/",
  "MAGIC_HEADER_NAME": "",
  "MAGIC_HEADER_VALUE": "",
  "SENTRY_DSN": "",
  "APP_SOCIAL_API_URL": "http://'mydomain':80/",
  "LINK_PREVIEWS_TRUSTED_PROXY_URL": "http://'mydomain':80/"
}

AndroidManifest.xml

<intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
                <data
                        android:scheme="http"
                        android:host="mydomain" -->without port
                        android:pathPrefix="/api/auth/"/>
            </intent-filter>
            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
                <data
                        android:scheme="https"
                        android:host="mydomain" -->without port
                        android:pathPrefix="/api/auth/"/>
        

Kindly help. I’ll provide more information if needed.Thanks in advance. Dont know but I feel the above could br related to the follwoing question i posted as a separate question :

LateInitializationError: Field 'apiURL' has not been initialized

>Solution :

Your value from api is null when you try to parse it, you need set default value to them. Change your fromJson to this:

factory Environment.fromJson(Map<String, dynamic> jsonMap) {
    return new Environment(
      apiUrl: jsonMap["API_URL"] ?? "",
      magicHeaderName: jsonMap["MAGIC_HEADER_NAME"] ?? "",
      magicHeaderValue: jsonMap["MAGIC_HEADER_VALUE"] ?? "",
      // intercomAppId: jsonMap["INTERCOM_APP_ID"] ?? "",
      // intercomIosKey: jsonMap["INTERCOM_IOS_KEY"] ?? "",
      // intercomAndroidKey: jsonMap["INTERCOM_ANDROID_KEY"] ?? "",
      sentryDsn: jsonMap["SENTRY_DSN"] ?? "",
      myappapiurl: jsonMap["KOSMOSNETWORK_SOCIAL_API_URL"] ?? "",
      linkPreviewsTrustedProxyUrl: jsonMap["LINK_PREVIEWS_TRUSTED_PROXY_URL"] ?? "",
    );
  }

or define your model’s variables as nullable:

class Environment {
  final String? apiUrl;
  final String? magicHeaderName;
  final String? magicHeaderValue;
  // final String? intercomIosKey;
  // final String? intercomAndroidKey;
  // final String? intercomAppId;
  final String? sentryDsn;
  final String? myappapiurl;
  final String? linkPreviewsTrustedProxyUrl;
...
}

both above ways are correct but you decide which one is works for you.

Leave a Reply