Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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 :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading