Flutter - Trouble launching app for debug on macOS

Viewed 19285

I've recently tried to migrate code from main.dart to the beginning of home_page.dart so as to steam line my application. Since doing this, my app now won't compile, I suspect as it doesn't know where to launch the application.

This is the error I'm receiving, Set the 'program' value in your launch config (eg 'bin/main.dart') then launch again (in VSCode) but since migrating the code I don't have main.dart, below is the last used version before deletion including the current version of home_page.dart

Also, below is the result of $ flutter doctor -v

main.dart;

import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:cryptick_nice_ui/dependency_injection.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:cryptick_nice_ui/home_page.dart';

void main() async {
  Injector.configure(Flavor.PROD);
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
          primarySwatch: Colors.pink,
          primaryColor: defaultTargetPlatform == TargetPlatform.iOS
              ? Colors.grey[100]
              : null),
      debugShowCheckedModeBanner: false,
      home: new HomePage(),
    );
  }
}

home_page.dart;

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:cryptick_nice_ui/data/crypto_data.dart';
import 'package:cryptick_nice_ui/modules/crypto_presenter.dart';
import 'background.dart';
import 'package:cryptick_nice_ui/dependency_injection.dart';

void main() async {
  Injector.configure(Flavor.PROD);
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
          primarySwatch: Colors.pink,
          primaryColor: defaultTargetPlatform == TargetPlatform.iOS
              ? Colors.grey[100]
              : null),
      debugShowCheckedModeBanner: false,
      home: new HomePage(),
    );
  }
}


class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> implements CryptoListViewContract {
  CryptoListPresenter _presenter;
  List<Crypto> _currencies;
  bool _isLoading;
  final List<MaterialColor> _colors = [Colors.blue, Colors.indigo, Colors.red];





  _HomePageState() {
    _presenter = new CryptoListPresenter(this);
  }

  @override
  void initState() {
    super.initState();
    _isLoading = true;
    _presenter.loadCurrencies();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text(".",
          style: new TextStyle(
            fontFamily: 'PlayfairDisplay',
            letterSpacing: 0.8,
            color: const Color(0xFF273A48),
          )
          ),
          backgroundColor: const Color(0xFF273A48),
          elevation: 0.0,
        ),
        body: _isLoading
            ? new Center(
          child: new CircularProgressIndicator(),
        )
            : _cryptoWidget()
      );
  }

    Widget _cryptoWidget() {
    final _width = MediaQuery.of(context).size.width;
    final _height = MediaQuery.of(context).size.height;
    return new Container(
      decoration: new BoxDecoration(
      color: const Color(0xFF273A48),
    ),
        child: new Column(
          children: <Widget>[
            new CustomPaint(
            size: new Size(_width, _height),
            painter: new Background(),
          ),
            new Flexible(
              child: new ListView.builder(
                itemCount: _currencies.length,
                itemBuilder: (BuildContext context, int index) {
                  final int i = index ~/ 2;
                  final Crypto currency = _currencies[i];
                  final MaterialColor color = _colors[i % _colors.length];
                  if (index.isOdd) {
                    return new Divider();
                  }
                  return _getListItemUi(context, currency, color);
                },
              ),
            )
          ],
        )
      );
  }



  Widget _getListItemUi(BuildContext context, Crypto currency, MaterialColor color) {
    final _width = MediaQuery.of(context).size.width;
    final _height = MediaQuery.of(context).size.height;
    _presenter.loadCurrencies();
    final headerList = new ListView.builder(
      itemBuilder: (context, index) {
        EdgeInsets padding = index == 0?const EdgeInsets.only(
            left: 20.0, right: 10.0, top: 4.0, bottom: 30.0):const EdgeInsets.only(
            left: 10.0, right: 10.0, top: 4.0, bottom: 30.0);

        return new Padding(
          padding: padding,
          child: new InkWell(
            onTap: () {
              print('Card selected');
            },
            child: new Container(
              decoration: new BoxDecoration(
                borderRadius: new BorderRadius.circular(10.0),
                color: Colors.lightGreen,
                boxShadow: [
                  new BoxShadow(
                      color: Colors.black.withAlpha(70),
                      offset: const Offset(3.0, 10.0),
                      blurRadius: 15.0)
                ],
                image: new DecorationImage(
                  image: new ExactAssetImage(
                      ''),
                  fit: BoxFit.fitHeight,
                ),
              ),
//                                    height: 200.0,
              width: 200.0,
              child: new Stack(
                children: <Widget>[
                  new Align(
                    alignment: Alignment.bottomCenter,
                    child: new Container(
                        decoration: new BoxDecoration(
                            color: const Color(0xFF273A48),
                            borderRadius: new BorderRadius.only(
                                bottomLeft: new Radius.circular(10.0),
                                bottomRight: new Radius.circular(10.0))),
                        height: 30.0,
                        child: new Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            new Text(
                              'hi',
                              style: new TextStyle(color: Colors.white),
                            )
                          ],
                        )),
                  )
                ],
              ),
            ),
          ),
        );
      },
      scrollDirection: Axis.horizontal,
      itemCount: _currencies.length,
    );

    final body = new Scaffold(
      appBar: new AppBar(
        title: new Text('cryp'),
        elevation: 0.0,
        backgroundColor: Colors.transparent,
        actions: <Widget>[
          new IconButton(icon: new Icon(Icons.shopping_cart, color: Colors.white,), onPressed: (){})
        ],
      ),
      backgroundColor: Colors.transparent,
      body: new Container(
        child: new Stack(
          children: <Widget>[
            new Padding(
              padding: new EdgeInsets.only(top: 10.0),
              child: new Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.start,
                children: <Widget>[
                  new Align(
                    alignment: Alignment.centerLeft,
                    child: new Padding(
                        padding: new EdgeInsets.only(left: 8.0),
                        child: new Text(
                          'Trending News',
                          style: new TextStyle(
                            color: Colors.white70,
                            fontSize: 15.0,
                            ),
                        )),
                  ),
                  new Container(
                      height: 300.0, width: _width, child: headerList),
                  new Expanded(child:
                  ListView.builder(itemBuilder: (context, index) {
                    return new ListTile(
                      title: new Column(
                        children: <Widget>[
                          new Row(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              new Container(
                                height: 72.0,
                                width: 72.0,
                                decoration: new BoxDecoration(
                                    color: Colors.lightGreen,
                                    boxShadow: [
                                      new BoxShadow(
                                          color:
                                          Colors.black.withAlpha(70),
                                          offset: const Offset(2.0, 2.0),
                                          blurRadius: 2.0)
                                    ],
                                    borderRadius: new BorderRadius.all(
                                        new Radius.circular(12.0)),
                                    image: new DecorationImage(
                                      image: new ExactAssetImage(
                                        "cryptoiconsBlack/"+currency.symbol.toLowerCase()+"@2x.png",
                                      ),
                                      fit: BoxFit.cover,
                                    )),
                              ),
                              new SizedBox(
                                width: 8.0,
                              ),
                              new Expanded(
                                  child: new Column(
                                    mainAxisAlignment:
                                    MainAxisAlignment.start,
                                    crossAxisAlignment:
                                    CrossAxisAlignment.start,
                                    children: <Widget>[
                                      new Text(
                                        'My item header',
                                        style: new TextStyle(
                                            fontSize: 14.0,
                                            color: Colors.black87,
                                            fontWeight: FontWeight.bold),
                                      ),
                                      new Text(
                                        'Item Subheader goes here\nLorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry',
                                        style: new TextStyle(
                                            fontSize: 12.0,
                                            color: Colors.black54,
                                            fontWeight: FontWeight.normal),
                                      )
                                    ],
                                  )),
                              new Icon(
                                Icons.shopping_cart,
                                color: const Color(0xFF273A48),
                              )
                            ],
                          ),
                          new Divider(),
                        ],
                      ),
                    );
                  }))
                ],
              ),
            ),
          ],
        ),
      ),
    );

    return new Container(
      decoration: new BoxDecoration(
        color: const Color(0xFF273A48),
      ),
      child: new Stack(
        children: <Widget>[
          new CustomPaint(
            size: new Size(_width, _height),
            painter: new Background(),
          ),
          body,
        ],
      ),
    );
  }



  Widget _getSubtitleText(String priceUSD, String percentageChange) {
    TextSpan priceTextWidget = new TextSpan(
        text: "\$$priceUSD\n", style: new TextStyle(color: Colors.black));
    String percentageChangeText = "1 hour: $percentageChange%";
    TextSpan percentageChangeTextWidget;

    if (double.parse(percentageChange) > 0) {
      percentageChangeTextWidget = new TextSpan(
          text: percentageChangeText,
          style: new TextStyle(color: Colors.green));
    } else {
      percentageChangeTextWidget = new TextSpan(
          text: percentageChangeText, style: new TextStyle(color: Colors.red));
    }

    return new RichText(
        text: new TextSpan(
            children: [priceTextWidget, percentageChangeTextWidget]));
  }



  @override
  void onLoadCryptoComplete(List<Crypto> items) {
    // TODO: implement onLoadCryptoComplete

    setState(() {
      _currencies = items;
      _isLoading = false;
    });
  }

  @override
  void onLoadCryptoError() {
    // TODO: implement onLoadCryptoError
    }
  }

Result of $flutter doctor -v

[✓] Flutter (Channel beta, v0.5.1, on Mac OS X 10.13.6 17G65, locale en-GB)
    • Flutter version 0.5.1 at /Users/Jake/flutter
    • Framework revision c7ea3ca377 (3 months ago), 2018-05-29 21:07:33 +0200
    • Engine revision 1ed25ca7b7
    • Dart version 2.0.0-dev.58.0.flutter-f981f09760

[✓] Android toolchain - develop for Android devices (Android SDK 28.0.2)
    • Android SDK at /Users/jake/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b01)
    • All Android licenses accepted.

[✓] iOS toolchain - develop for iOS devices (Xcode 9.4.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 9.4.1, Build version 9F2000
    • ios-deploy 1.9.2
    • CocoaPods version 1.5.3

[✓] Android Studio (version 3.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b01)

[✓] Connected devices (1 available)
    • Nokia 3310 • b689ec530586d0c681cac2136a29548cfbe7c9a6 • ios • iOS 11.4.1

• No issues found!
4 Answers

open .vscode/launch.json

and inside "configurations" add "program"

"configurations": [
         {
            "name": "Flutter",
            "request": "launch",
            "type": "dart",
            "program": "lib/your_class/file_name_with_main_function.dart"
        }
    ]

Replace 'lib' with folder and 'your_class/file_name_with_main_function' with the class name that hold main function

This happens when your main.dart (the starting point of your flutter app) is not in your /lib folder. How to fix: Add this line in your launch.json file, under "Configurations":

["program": "/${workspaceFolder}/lib/screens/home/main.dart"]

You could theoretically change an option in Debug > Open Configurations to make it run a different file, although I don't see the option. But even if you figure that out, it probably isn't advisable. When you do a 'build' to deploy the app, it's probably going to assume main.dart is the file to run and might fail if it can't find it.

I'd advise keeping a main.dart - it could have just the void main() function and the rest of your code could be elsewhere, but at least then someone else coming looking at your code will be able to recognize where the main is.

I experienced such an issue (on windows). I fixed it by adding the following code to my launch.json:

"program": "/Users/user/classes_advanced/animal.dart"

The /Users/user/classes_advanced/animal.dart is my file path name. Just right-click on the program you want to launch and copy the PATH. Then replace my own with yours. Make sure to replace the slash / with \ accordingly.

Related