Search code examples
flutterlistdartinitializer

Dart creating constructor without this keyword


I could not get the constructor logic with the below code block. In the named constructors we use ClassName({this.variable or required this.variable}); But, in the below example the developer choose a different way. It uses initializer list too but could not get the logic why it defines a variable like this

MetaWeatherApiClient? weatherApiClient

in the constructor's body?

class WeatherRepository {
  WeatherRepository({
    MetaWeatherApiClient? weatherApiClient
  }) : _weatherApiClient = weatherApiClient ?? MetaWeatherApiClient();

  final MetaWeatherApiClient _weatherApiClient;

  Future<Weather> getWeather(String city) async {
    final location = await _weatherApiClient.locationSearch(city);
    final woeid = location.woeid;
    final weather = await _weatherApiClient.getWeather(woeid);
    return Weather(
      temperature: weather.theTemp,
      location: location.title,
      condition: weather.weatherStateAbbr.toCondition,
    );
  }
}

Solution

  • If you have a code like shown below

    class SomeClass {
      SomeClass({
        required this.a,
      });
    
      final int a;
    }
    

    Now when you initialize the SomeClass object, you will have to do this.

    final obj = SomeClass(a: 1);
    

    i.e. you will manually need to pass the constructor parameter in this case.

    But if I did something like this

    class SomeClass {
      SomeClass({int? a}) : _a = a ?? 1;
    
      final int _a;
    }
    

    Now if I wanted to create an instance of SomeClass, I can just do,

    final obj = SomeClass();
    

    Here, I don't need to pass the constructor parameter as the constructor parameter is nullable. And in the initializer list I have a condition that if the parameter is null, assign the default value as 1.

    In the code that you shared, you can make a WeatherRepository instance simply by doing

    final obj = WeatherRepository();
    

    You needn't explicitly mention the dependency of WeatherRepository as it is a nullable variable and when it is null the condition in the initializer list will anyhow initialize the dependency.

    You didn't have to do this to create an instance of WeatherRepository.

    final obj = WeatherRepository(MetaWeatherApiClient());
    

    Ultimately helping to write clean and readable code (at least when object initialization needs to take place)

    In the case you don't know how the expression

    var a = b ?? c;
    

    works, then this is equivalent to

    if(b != null) {
      var a = b;
    } else {
      var a = c;
    }