问:
How to handle user registration error using Bloc pattern in flutter

Here is some code i've tried. in this code i've used bloc. but i want to error handling in this signup page.

when user is register if registration is succefully then and then only OTP Dialog need to open

When the user regisering is failed the user get appropriate meesage.

if signup is in the process the loading should be indicated.

after successfully registered. it will be shown an OTP. after entering otp it will redirect another Alert Dialog. Hope you understand the question please help me. I tried many time error handling also in this code you find an error handling but it's not proper. I hope you can help me. you little help can make my day.

Here Is full Source Code https://github.com/rutvikgumasana/signup/tree/master

.

```import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_masked_text/flutter_masked_text.dart';

import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:passcode/passcode.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tudo/src/modules/signup/_models/countries.dart';
import 'package:tudo/src/modules/signup/index.dart';
import 'package:tudo/src/styles/colors.dart';

import 'package:tudo/src/utils/app_constants_value.dart';
import 'package:tudo/src/utils/navigation_helper.dart';
import 'package:tudo/src/utils/roundrectbutton.dart';
import 'package:tudo/src/utils/validator.dart';
import 'package:tudo/src/widgets/loader.dart';

import 'package:tudo/src/widgets/toast.dart';
import 'dart:math' as math;

class SignupScreen extends StatefulWidget {
  const SignupScreen({
    Key key,
    @required SignupBloc signupBloc,
  })  : _signupBloc = signupBloc,
        super(key: key);

  final SignupBloc _signupBloc;

  @override
  SignupScreenState createState() {
    return new SignupScreenState(_signupBloc);
  }
}

class SignupScreenState extends State<SignupScreen>
    with TickerProviderStateMixin {
  String submittedString = "";
  final changeNotifier = StreamController<Functions>.broadcast();

  final SignupBloc _signupBloc;
  SignupScreenState(this._signupBloc);
  final formKey = new GlobalKey<FormState>();
  bool _validate = false;
  List<Country> _countries = [];
  bool _isError = false;
  bool _isLoading = false;
  bool _obscureText = true;
  Person person = new Person();
  var controller = new MaskedTextController(mask: '(000)-000-0000');

  String passcode;
  final _emailFocusNode = new FocusNode();
  final _passwordFocusNode = new FocusNode();
  final _fnameFocuNode = new FocusNode();
  final _lnameFocusNode = new FocusNode();
  final TextEditingController _email = new TextEditingController();
  final TextEditingController _add = new TextEditingController();
  final TextEditingController _fn = new TextEditingController();
  final TextEditingController _ln = new TextEditingController();
  final TextEditingController _pho = new TextEditingController();
  final TextEditingController _pass = new TextEditingController();

  TextEditingController phoneController = new TextEditingController();

  static List<CountryModel> _dropdownItems = new List();

  String otpWaitTimeLabel = "";

  CountryModel _dropdownValue;
  TextEditingController otpcontroller = TextEditingController();
  String thisText = "";
  int pinLength = 6;

  bool hasError = false;
  bool showAlertBox = false;
  String errorMessage;

  SharedPreferences prefs;
  DateTime target;
  String timeLeft = "";
  bool running = true;

  @override
  void initState() {
    super.initState();

    this._signupBloc.dispatch(LoadSignupEvent());
  }

  @override
  void dispose() {
    prefs.setInt('target', target.millisecondsSinceEpoch);
    running = false;
    super.dispose();
  }

  void _toggle() {
    setState(() {
      _obscureText = !_obscureText;
    });
  }

  Widget _buildLogo() {
    return new Image(
      image: new AssetImage("assets/logo.png"),
      height: 150,
      width: 150,
    );
  }

  Widget _buildEmailField() {
    return TextFormField(
      controller: _email,
      focusNode: _emailFocusNode,
      decoration: new InputDecoration(
        prefixIcon: Icon(
          Icons.email,
        ),
        labelText: AppConstantsValue.appConst['signup']['email']['translation'],
        border: UnderlineInputBorder(),
        filled: false,
        hintText: 'Your email address',
      ),
      keyboardType: TextInputType.emailAddress,
      validator: Validators().validateEmail,
      onSaved: (String value) {
        person.email = value;
      },
    );
  }

  Widget _buildCountry(List<Country> countries) {
    if (countries.length > 0 && _dropdownItems.length != countries.length - 1) {
      print("countries list");
      print(countries[0].name);
      for (int i = 0; i < countries.length; i++) {
        if (countries[i].name.toLowerCase() != 'world') {
          _dropdownItems.add(
            CountryModel(
                country: countries[i].name, countryCode: countries[i].isdCode),
          );
        }
      }
    }
    return FormBuilder(
      autovalidate: true,
      initialValue: {},
      child: FormBuilderCustomField(
        attribute: "Country",
        validators: [
          FormBuilderValidators.required(),
        ],
        formField: FormField(
          builder: (FormFieldState<dynamic> field) {
            return DropdownButtonHideUnderline(
              child: new Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  new InputDecorator(
                    decoration: InputDecoration(
                      filled: false,
                      hintText: 'Choose Country',
                      prefixIcon: Icon(Icons.location_on),
                      labelText: _dropdownValue == null
                          ? 'Where are you from'
                          : 'From',
                      errorText: field.errorText,
                    ),
                    isEmpty: _dropdownValue == null,
                    child: new DropdownButton<CountryModel>(
                      value: _dropdownValue,
                      isDense: true,
                      onChanged: (CountryModel newValue) {
                        print('value change');
                        print(newValue);
                        person.country = newValue.country;
                        person.countryCode = newValue.countryCode;
                        setState(() {
                          _dropdownValue = newValue;
                          phoneController.text = _dropdownValue.countryCode;
                          field.didChange(newValue);
                        });
                      },
                      items: _dropdownItems.map(
                        (CountryModel value) {
                          return DropdownMenuItem<CountryModel>(
                            value: value,
                            child: Text(value.country),
                          );
                        },
                      ).toList(),
                    ),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }

  Widget _buildPhonefiled() {
    return Row(
      children: <Widget>[
        new Expanded(
          child: new TextFormField(
            controller: phoneController,
            enabled: false,
            decoration: InputDecoration(
              filled: false,
              prefixIcon: Icon(FontAwesomeIcons.globe),
              labelText: 'code',
              hintText: "Country code",
            ),
          ),
          flex: 2,
        ),
        new SizedBox(
          width: 10.0,
        ),
        new Expanded(
          child: new TextFormField(
            controller: controller,
            keyboardType: TextInputType.number,
            validator: Validators().validateMobile,
            decoration: InputDecoration(
              filled: false,
              labelText: 'mobile',
              hintText: "Mobile number",
              prefixIcon: new Icon(Icons.mobile_screen_share),
            ),
            onSaved: (String value) {
              person.phoneNumber = value;
            },
          ),
          flex: 5,
        ),
      ],
    );
  }

  Widget _buildFnamefiled() {
    return TextFormField(
      controller: _fn,
      focusNode: _fnameFocuNode,
      decoration: new InputDecoration(
          filled: false,
          hintText: 'Enter your First name',
          prefixIcon: Icon(
            Icons.account_circle,
            //  size: 28.0,
          ),
          labelText: AppConstantsValue.appConst['signup']['firstname']
              ['translation']),
      keyboardType: TextInputType.text,
      validator: Validators().validateName,
      onSaved: (String value) {
        person.firstname = value;
      },
    );
  }

  Widget _buildLnamefiled() {
    return TextFormField(
      validator: Validators().validateName,
      controller: _ln,
      focusNode: _lnameFocusNode,
      decoration: new InputDecoration(
          filled: false,
          hintText: 'Enter your Last name',
          prefixIcon: Icon(
            Icons.account_circle,
            //  size: 28.0,
          ),
          labelText: AppConstantsValue.appConst['signup']['lastname']
              ['translation']),
      keyboardType: TextInputType.text,
      onSaved: (String value) {
        person.lastname = value;
      },
    );
  }

  Widget _buildPasswordfiled() {
    return TextFormField(
      validator: Validators().validatePassword,
      obscureText: _obscureText,
      controller: _pass,
      focusNode: _passwordFocusNode,
      decoration: new InputDecoration(
        filled: false,
        hintText: 'Enter your password',
        prefixIcon: Icon(
          Icons.vpn_key,
        ),
        suffixIcon: GestureDetector(
          dragStartBehavior: DragStartBehavior.down,
          onTap: _toggle,
          child: Icon(
            _obscureText ? Icons.visibility : Icons.visibility_off,
            semanticLabel: _obscureText
                ? AppConstantsValue.appConst['login']['show_password']
                    ['translation']
                : AppConstantsValue.appConst['login']['hide_password']
                    ['translation'],
          ),
        ),
        labelText: AppConstantsValue.appConst['signup']['password']
            ['translation'],
      ),
      onSaved: (String value) {
        person.password = value;
      },
    );
  }

  Widget _buildTermsAndContionsCheck() {
    return FormField(
      builder: (FormFieldState state) {
        return Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            Checkbox(
              value: person.termsAndCondition,
              onChanged: (bool value) {
                setState(() {
                  person.termsAndCondition = value;
                });
              },
            ),
            Text(
              AppConstantsValue.appConst['signup']['termsandcondition']
                  ['translation'],
            ),
          ],
        );
      },
    );
  }

  _onAlertotp() {
    return showDialog<void>(
      context: context,
      barrierDismissible: false, // user must tap button!
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Enter OTP'),
          content: SingleChildScrollView(
            child: ListBody(
              children: <Widget>[
                Container(
                  height: MediaQuery.of(context).size.height / 2.4,
                  width: MediaQuery.of(context).size.width,
                  alignment: Alignment.center,
                  child: ListView(
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.symmetric(vertical: 8.0),
                        child: Text(
                          'We have Texted and/or Emailed OTP (One Time Pin) to your registered cell phone and/ or email account. Please check and enter OTP below to activate your TUDO account.',
                          style: TextStyle(
                              fontWeight: FontWeight.bold, fontSize: 15),
                          textAlign: TextAlign.center,
                        ),
                      ),
                      Center(
                        child: Text(
                          "timerString",
                          style: TextStyle(fontSize: 25),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.symmetric(
                            vertical: 8.0, horizontal: 30),
                        child: PinCodeTextField(
                          length: 6, // must be greater than 0
                          obsecureText: false, //optional, default is false
                          shape: PinCodeFieldShape
                              .underline, //optional, default is underline
                          onDone: (String value) {
                            setState(() {
                              passcode = value;
                              print(value);
                            });
                          },

                          textStyle: TextStyle(
                              fontWeight: FontWeight
                                  .bold), //optinal, default is TextStyle(fontSize: 18, color: Colors.black, fontWeight: FontWeight.bold)
                          onErrorCheck: (bool value) {
                            setState(() {
                              hasError = value;
                            });
                          },
                          shouldTriggerFucntions:
                              changeNotifier.stream.asBroadcastStream(),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 30.0),
                        child: Text(
                          hasError
                              ? "*Please fill up all the cells and press VERIFY again"
                              : "",
                          style: TextStyle(
                              color: Colors.red.shade300, fontSize: 12),
                        ),
                      ),
                      SizedBox(
                        height: 5,
                      ),
                      RichText(
                        textAlign: TextAlign.center,
                        text: TextSpan(
                            text: "Didn't receive the code? ",
                            style:
                                TextStyle(color: Colors.black54, fontSize: 15),
                            children: [
                              TextSpan(
                                  text: " RESEND",
                                  // recognizer: onTapRecognizer,
                                  style: TextStyle(
                                      color: colorStyles["primary"],
                                      fontWeight: FontWeight.bold,
                                      fontSize: 16))
                            ]),
                      ),
                      SizedBox(
                        height: 7,
                      ),
                      Container(
                        margin: const EdgeInsets.symmetric(
                            vertical: 16.0, horizontal: 30),
                        child: ButtonTheme(
                          height: 50,
                          child: FlatButton(
                            onPressed: () async {
                              _onAlertrunnigbusiness(context);
                            },
                            child: Center(
                                child: Text(
                              "VERIFY".toUpperCase(),
                              style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 18,
                                  fontWeight: FontWeight.bold),
                            )),
                          ),
                        ),
                        decoration: BoxDecoration(
                          color: colorStyles["primary"],
                          borderRadius: BorderRadius.circular(5),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
          actions: <Widget>[
            FlatButton(
              child: Text('Close'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  _onAlertrunnigbusiness(context) {
    return showDialog<void>(
      context: context,
      barrierDismissible: false, // user must tap button!
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Are you running Business?'),
          content: Container(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                SizedBox(
                  height: 10,
                ),
                Text(
                    "TUDO.App aims at Businesses bridging gaps between Business Service Providers and Consumers collaborate on unique technology platform. If you own a business, we strongly recommend, provide your business information to grow your customer base and expand your business services. Any questions? Call us @1-800-888-TUDO"),
                SizedBox(
                  height: 10,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    FlatButton.icon(
                      icon: Icon(FontAwesomeIcons.arrowCircleRight),
                      label: Text('No'),
                      color: colorStyles["primary"],
                      textColor: Colors.white,
                      padding:
                          EdgeInsets.symmetric(vertical: 10, horizontal: 15),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(7),
                      ),
                      onPressed: () {
                        NavigationHelper.navigatetoMainscreen(context);
                      },
                    ),
                    SizedBox(height: 10),
                    FlatButton.icon(
                      icon: Icon(FontAwesomeIcons.arrowCircleRight),
                      label: Text('Yes'),
                      color: colorStyles["primary"],
                      textColor: Colors.white,
                      padding:
                          EdgeInsets.symmetric(vertical: 10, horizontal: 15),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(7),
                      ),
                      onPressed: () {
                        NavigationHelper.navigatetoBspsignupcreen(context);
                      },
                    ),
                  ],
                )
              ],
            ),
          ),
          actions: <Widget>[
            FlatButton(
              child: Text('Close'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  Widget _buildClearButton() {
    return new FlatButton(
      onPressed: () {
        _email.clear();
        _fn.clear();
        _ln.clear();
        _pho.clear();
        _add.clear();
        _pass.clear();
        _isError = false;

        setState(() {
          _isError = false;
        });
      },
      child: Text(
        AppConstantsValue.appConst['signup']['clear']['translation'],
        style: TextStyle(letterSpacing: 1.5),
      ),
    );
  }

  Widget _buildSignupButton(SignupBloc signupBloc, BuildContext context) {
    return GestureDetector(
      child: RoundrectButton.buildRoundedRectButton(
          AppConstantsValue.appConst['signup']['signup']['translation'],
          signUpGradients,
          false),
      onTap: () {
        //  _submit();
        final FormState form = formKey.currentState;
        form.save();
        if (form.validate() && person.termsAndCondition) {
          setState(() {
            _isLoading = true;
          });
          Map<String, dynamic> signupdata = {
            'email': person.email,
            'country': person.country,
            'countyCode': person.countryCode,
            'phoneNumber': person.phoneNumber,
            'firstName': person.firstname,
            'lastName': person.lastname,
            'password': person.password,
          };
          _isError
              ? new Container(child: Text("Error"))
              : widget._signupBloc.dispatch(
                  SignupButtonClickedEvent(signupdata: signupdata),
                );
        } else {
          print("Toast is printed");
          Errortoast().showColoredToast();
          setState(() {
            _isLoading = false;
            _validate = true;
          });
        }
      },
    );
  }

  Widget _buildBackButton(BuildContext context) {
    return FlatButton(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Icon(Icons.arrow_back_ios),
          Text(AppConstantsValue.appConst['signup']['backtologin']
              ['translation'])
        ],
      ),
      onPressed: () => Navigator.pop(context, false),
    );
  }

  Widget _buildLoader() {
    return Loader(
      color: colorStyles["primary"],
    );
  }

  Widget content(signupBloc, context, List<Country> countries) {
    return SafeArea(
      top: false,
      bottom: false,
      child: Form(
        key: formKey,
        autovalidate: _validate,
        child: Scrollbar(
          child: SingleChildScrollView(
            dragStartBehavior: DragStartBehavior.down,
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            child: new Container(
              margin: EdgeInsets.fromLTRB(30, 0, 30, 0),
              child: new Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  _buildLogo(),
                  _buildEmailField(),
                  _buildCountry(countries),
                  _buildPhonefiled(),
                  _buildFnamefiled(),
                  _buildLnamefiled(),
                  _buildPasswordfiled(),
                  _buildTermsAndContionsCheck(),
                  SizedBox(),
                  _isError ? new Text('Fail to signup') : SizedBox(),
                  _isLoading ? _buildLoader() : SizedBox(),
                  _buildClearButton(),
                  _buildSignupButton(signupBloc, context),
                  _buildBackButton(context),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<SignupBloc, SignupState>(
      bloc: widget._signupBloc,
      builder: (
        BuildContext context,
        SignupState currentState,
      ) {
        if (currentState is UnSignupState) {
          return Container(
            height: MediaQuery.of(context).size.height / 1.10,
            width: MediaQuery.of(context).size.width / 1.10,
            child: Center(
              child: _buildLoader(),
            ),
          );
        }

        if (currentState is ErrorSignupState) {
          _isLoading = false;
          _isError = true;
          showAlertBox = false;
          return Container(
            child: content(_signupBloc, context, _countries),
          );
        }
        if (currentState is InSignupState) {
          _countries = currentState.countries.countries;
          return Container(child: content(_signupBloc, context, _countries));
        }

        if (currentState is SignupButtonClickedEvent) {
          print('SignupButtonClickedEvent clicked');
          return Container();
        }

        if (currentState is SignupSuccessState) {
          print(
              ' You are awesome. you have successfully registered without confirmation');
          print(currentState.signupUser.toJson());
          print("Hey Otp Is opned");
          WidgetsBinding.instance.addPostFrameCallback((_) {
            // _never();

            _onAlertotp();
          });
          _isLoading = false;
          showAlertBox = true;
          return Container(
            child: content(_signupBloc, context, _countries),
          );
        }

        if (currentState is SignupVerficationOtp) {
          print('signup verficitaion otp button clicked');
          return Container();
        }
        return Container(child: content(_signupBloc, context, _countries));
      },
    );
  }
}

class Person {
  String email = '';
  String country = '';
  String countryCode = '';
  String phoneNumber = '';
  String firstname = '';
  String lastname = '';
  String password = '';
  bool termsAndCondition = false;
}

class CountryModel {
  String country = '';
  String countryCode = '';

  CountryModel({
    this.country,
    this.countryCode,
  });
}
```

答:
First of all if you are using Bloc Pattern you can't use setState. Other thing is you should make a new class for a bloc. In your case RegistrationBloc. Then Import RxDart.

```<code>class SignupBloc{

String _nameValue;

BehaviourSubject<String> _nameSubject = BehaviourSubject<String>();
Stream<String> get nameStream => _nameSubject.stream;
StreamController<String> _name = StreamController<String>();
Sink<String> get nameSink => _name.sink;

SignupBloc(){

   //Inside the StreamController you can do anything to your value
   _name.stream.listen((name){
      if(name == "" || name == null){
         _nameSubject.addError("Please Enter Your Name");
      }else{
         _nameValue = name;
      }
   }
}
</code>```

Make sure you firs create and Instance of Your Bloc

```<code>SignUpBloc _signUpBloc = SignInBloc();
</code>```

Your Text Field Should Be like this

```<code>StreamBuilder<String>(
  stream: _signUpBloc.nameStream,
  builder: (context, snapshot) {
    return TextField(
      onChanged: (value) => _signUpBloc.nameSink.add(value),
      decoration: InputDecoration(
          labelText: "label", errorText: snapshot.error),
    );
  }
);
</code>```

Body:
Here is some code i've tried. in this code i've used bloc. but i want to error handling in this signup page.

when user is register if registration is succefully then and then only OTP Dialog need to open

When the user regisering is failed the user get appropriate meesage.

if signup is in the process the loading should be indicated.

after successfully registered. it will be shown an OTP. after entering otp it will redirect another Alert Dialog. Hope you understand the question please help me. I tried many time error handling also in this code you find an error handling but it's not proper. I hope you can help me. you little help can make my day.

Here Is full Source Code https://github.com/rutvikgumasana/signup/tree/master

.

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_masked_text/flutter_masked_text.dart';

import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:passcode/passcode.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tudo/src/modules/signup/_models/countries.dart';
import 'package:tudo/src/modules/signup/index.dart';
import 'package:tudo/src/styles/colors.dart';

import 'package:tudo/src/utils/app_constants_value.dart';
import 'package:tudo/src/utils/navigation_helper.dart';
import 'package:tudo/src/utils/roundrectbutton.dart';
import 'package:tudo/src/utils/validator.dart';
import 'package:tudo/src/widgets/loader.dart';

import 'package:tudo/src/widgets/toast.dart';
import 'dart:math' as math;

class SignupScreen extends StatefulWidget {
  const SignupScreen({
    Key key,
    @required SignupBloc signupBloc,
  })  : _signupBloc = signupBloc,
        super(key: key);

  final SignupBloc _signupBloc;

  @override
  SignupScreenState createState() {
    return new SignupScreenState(_signupBloc);
  }
}

class SignupScreenState extends State<SignupScreen>
    with TickerProviderStateMixin {
  String submittedString = "";
  final changeNotifier = StreamController<Functions>.broadcast();

  final SignupBloc _signupBloc;
  SignupScreenState(this._signupBloc);
  final formKey = new GlobalKey<FormState>();
  bool _validate = false;
  List<Country> _countries = [];
  bool _isError = false;
  bool _isLoading = false;
  bool _obscureText = true;
  Person person = new Person();
  var controller = new MaskedTextController(mask: '(000)-000-0000');

  String passcode;
  final _emailFocusNode = new FocusNode();
  final _passwordFocusNode = new FocusNode();
  final _fnameFocuNode = new FocusNode();
  final _lnameFocusNode = new FocusNode();
  final TextEditingController _email = new TextEditingController();
  final TextEditingController _add = new TextEditingController();
  final TextEditingController _fn = new TextEditingController();
  final TextEditingController _ln = new TextEditingController();
  final TextEditingController _pho = new TextEditingController();
  final TextEditingController _pass = new TextEditingController();

  TextEditingController phoneController = new TextEditingController();

  static List<CountryModel> _dropdownItems = new List();

  String otpWaitTimeLabel = "";

  CountryModel _dropdownValue;
  TextEditingController otpcontroller = TextEditingController();
  String thisText = "";
  int pinLength = 6;

  bool hasError = false;
  bool showAlertBox = false;
  String errorMessage;

  SharedPreferences prefs;
  DateTime target;
  String timeLeft = "";
  bool running = true;

  @override
  void initState() {
    super.initState();

    this._signupBloc.dispatch(LoadSignupEvent());
  }

  @override
  void dispose() {
    prefs.setInt('target', target.millisecondsSinceEpoch);
    running = false;
    super.dispose();
  }

  void _toggle() {
    setState(() {
      _obscureText = !_obscureText;
    });
  }

  Widget _buildLogo() {
    return new Image(
      image: new AssetImage("assets/logo.png"),
      height: 150,
      width: 150,
    );
  }

  Widget _buildEmailField() {
    return TextFormField(
      controller: _email,
      focusNode: _emailFocusNode,
      decoration: new InputDecoration(
        prefixIcon: Icon(
          Icons.email,
        ),
        labelText: AppConstantsValue.appConst['signup']['email']['translation'],
        border: UnderlineInputBorder(),
        filled: false,
        hintText: 'Your email address',
      ),
      keyboardType: TextInputType.emailAddress,
      validator: Validators().validateEmail,
      onSaved: (String value) {
        person.email = value;
      },
    );
  }

  Widget _buildCountry(List<Country> countries) {
    if (countries.length > 0 && _dropdownItems.length != countries.length - 1) {
      print("countries list");
      print(countries[0].name);
      for (int i = 0; i < countries.length; i++) {
        if (countries[i].name.toLowerCase() != 'world') {
          _dropdownItems.add(
            CountryModel(
                country: countries[i].name, countryCode: countries[i].isdCode),
          );
        }
      }
    }
    return FormBuilder(
      autovalidate: true,
      initialValue: {},
      child: FormBuilderCustomField(
        attribute: "Country",
        validators: [
          FormBuilderValidators.required(),
        ],
        formField: FormField(
          builder: (FormFieldState<dynamic> field) {
            return DropdownButtonHideUnderline(
              child: new Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  new InputDecorator(
                    decoration: InputDecoration(
                      filled: false,
                      hintText: 'Choose Country',
                      prefixIcon: Icon(Icons.location_on),
                      labelText: _dropdownValue == null
                          ? 'Where are you from'
                          : 'From',
                      errorText: field.errorText,
                    ),
                    isEmpty: _dropdownValue == null,
                    child: new DropdownButton<CountryModel>(
                      value: _dropdownValue,
                      isDense: true,
                      onChanged: (CountryModel newValue) {
                        print('value change');
                        print(newValue);
                        person.country = newValue.country;
                        person.countryCode = newValue.countryCode;
                        setState(() {
                          _dropdownValue = newValue;
                          phoneController.text = _dropdownValue.countryCode;
                          field.didChange(newValue);
                        });
                      },
                      items: _dropdownItems.map(
                        (CountryModel value) {
                          return DropdownMenuItem<CountryModel>(
                            value: value,
                            child: Text(value.country),
                          );
                        },
                      ).toList(),
                    ),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }

  Widget _buildPhonefiled() {
    return Row(
      children: <Widget>[
        new Expanded(
          child: new TextFormField(
            controller: phoneController,
            enabled: false,
            decoration: InputDecoration(
              filled: false,
              prefixIcon: Icon(FontAwesomeIcons.globe),
              labelText: 'code',
              hintText: "Country code",
            ),
          ),
          flex: 2,
        ),
        new SizedBox(
          width: 10.0,
        ),
        new Expanded(
          child: new TextFormField(
            controller: controller,
            keyboardType: TextInputType.number,
            validator: Validators().validateMobile,
            decoration: InputDecoration(
              filled: false,
              labelText: 'mobile',
              hintText: "Mobile number",
              prefixIcon: new Icon(Icons.mobile_screen_share),
            ),
            onSaved: (String value) {
              person.phoneNumber = value;
            },
          ),
          flex: 5,
        ),
      ],
    );
  }

  Widget _buildFnamefiled() {
    return TextFormField(
      controller: _fn,
      focusNode: _fnameFocuNode,
      decoration: new InputDecoration(
          filled: false,
          hintText: 'Enter your First name',
          prefixIcon: Icon(
            Icons.account_circle,
            //  size: 28.0,
          ),
          labelText: AppConstantsValue.appConst['signup']['firstname']
              ['translation']),
      keyboardType: TextInputType.text,
      validator: Validators().validateName,
      onSaved: (String value) {
        person.firstname = value;
      },
    );
  }

  Widget _buildLnamefiled() {
    return TextFormField(
      validator: Validators().validateName,
      controller: _ln,
      focusNode: _lnameFocusNode,
      decoration: new InputDecoration(
          filled: false,
          hintText: 'Enter your Last name',
          prefixIcon: Icon(
            Icons.account_circle,
            //  size: 28.0,
          ),
          labelText: AppConstantsValue.appConst['signup']['lastname']
              ['translation']),
      keyboardType: TextInputType.text,
      onSaved: (String value) {
        person.lastname = value;
      },
    );
  }

  Widget _buildPasswordfiled() {
    return TextFormField(
      validator: Validators().validatePassword,
      obscureText: _obscureText,
      controller: _pass,
      focusNode: _passwordFocusNode,
      decoration: new InputDecoration(
        filled: false,
        hintText: 'Enter your password',
        prefixIcon: Icon(
          Icons.vpn_key,
        ),
        suffixIcon: GestureDetector(
          dragStartBehavior: DragStartBehavior.down,
          onTap: _toggle,
          child: Icon(
            _obscureText ? Icons.visibility : Icons.visibility_off,
            semanticLabel: _obscureText
                ? AppConstantsValue.appConst['login']['show_password']
                    ['translation']
                : AppConstantsValue.appConst['login']['hide_password']
                    ['translation'],
          ),
        ),
        labelText: AppConstantsValue.appConst['signup']['password']
            ['translation'],
      ),
      onSaved: (String value) {
        person.password = value;
      },
    );
  }

  Widget _buildTermsAndContionsCheck() {
    return FormField(
      builder: (FormFieldState state) {
        return Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            Checkbox(
              value: person.termsAndCondition,
              onChanged: (bool value) {
                setState(() {
                  person.termsAndCondition = value;
                });
              },
            ),
            Text(
              AppConstantsValue.appConst['signup']['termsandcondition']
                  ['translation'],
            ),
          ],
        );
      },
    );
  }

  _onAlertotp() {
    return showDialog<void>(
      context: context,
      barrierDismissible: false, // user must tap button!
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Enter OTP'),
          content: SingleChildScrollView(
            child: ListBody(
              children: <Widget>[
                Container(
                  height: MediaQuery.of(context).size.height / 2.4,
                  width: MediaQuery.of(context).size.width,
                  alignment: Alignment.center,
                  child: ListView(
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.symmetric(vertical: 8.0),
                        child: Text(
                          'We have Texted and/or Emailed OTP (One Time Pin) to your registered cell phone and/ or email account. Please check and enter OTP below to activate your TUDO account.',
                          style: TextStyle(
                              fontWeight: FontWeight.bold, fontSize: 15),
                          textAlign: TextAlign.center,
                        ),
                      ),
                      Center(
                        child: Text(
                          "timerString",
                          style: TextStyle(fontSize: 25),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.symmetric(
                            vertical: 8.0, horizontal: 30),
                        child: PinCodeTextField(
                          length: 6, // must be greater than 0
                          obsecureText: false, //optional, default is false
                          shape: PinCodeFieldShape
                              .underline, //optional, default is underline
                          onDone: (String value) {
                            setState(() {
                              passcode = value;
                              print(value);
                            });
                          },

                          textStyle: TextStyle(
                              fontWeight: FontWeight
                                  .bold), //optinal, default is TextStyle(fontSize: 18, color: Colors.black, fontWeight: FontWeight.bold)
                          onErrorCheck: (bool value) {
                            setState(() {
                              hasError = value;
                            });
                          },
                          shouldTriggerFucntions:
                              changeNotifier.stream.asBroadcastStream(),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 30.0),
                        child: Text(
                          hasError
                              ? "*Please fill up all the cells and press VERIFY again"
                              : "",
                          style: TextStyle(
                              color: Colors.red.shade300, fontSize: 12),
                        ),
                      ),
                      SizedBox(
                        height: 5,
                      ),
                      RichText(
                        textAlign: TextAlign.center,
                        text: TextSpan(
                            text: "Didn't receive the code? ",
                            style:
                                TextStyle(color: Colors.black54, fontSize: 15),
                            children: [
                              TextSpan(
                                  text: " RESEND",
                                  // recognizer: onTapRecognizer,
                                  style: TextStyle(
                                      color: colorStyles["primary"],
                                      fontWeight: FontWeight.bold,
                                      fontSize: 16))
                            ]),
                      ),
                      SizedBox(
                        height: 7,
                      ),
                      Container(
                        margin: const EdgeInsets.symmetric(
                            vertical: 16.0, horizontal: 30),
                        child: ButtonTheme(
                          height: 50,
                          child: FlatButton(
                            onPressed: () async {
                              _onAlertrunnigbusiness(context);
                            },
                            child: Center(
                                child: Text(
                              "VERIFY".toUpperCase(),
                              style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 18,
                                  fontWeight: FontWeight.bold),
                            )),
                          ),
                        ),
                        decoration: BoxDecoration(
                          color: colorStyles["primary"],
                          borderRadius: BorderRadius.circular(5),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
          actions: <Widget>[
            FlatButton(
              child: Text('Close'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  _onAlertrunnigbusiness(context) {
    return showDialog<void>(
      context: context,
      barrierDismissible: false, // user must tap button!
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Are you running Business?'),
          content: Container(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                SizedBox(
                  height: 10,
                ),
                Text(
                    "TUDO.App aims at Businesses bridging gaps between Business Service Providers and Consumers collaborate on unique technology platform. If you own a business, we strongly recommend, provide your business information to grow your customer base and expand your business services. Any questions? Call us @1-800-888-TUDO"),
                SizedBox(
                  height: 10,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    FlatButton.icon(
                      icon: Icon(FontAwesomeIcons.arrowCircleRight),
                      label: Text('No'),
                      color: colorStyles["primary"],
                      textColor: Colors.white,
                      padding:
                          EdgeInsets.symmetric(vertical: 10, horizontal: 15),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(7),
                      ),
                      onPressed: () {
                        NavigationHelper.navigatetoMainscreen(context);
                      },
                    ),
                    SizedBox(height: 10),
                    FlatButton.icon(
                      icon: Icon(FontAwesomeIcons.arrowCircleRight),
                      label: Text('Yes'),
                      color: colorStyles["primary"],
                      textColor: Colors.white,
                      padding:
                          EdgeInsets.symmetric(vertical: 10, horizontal: 15),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(7),
                      ),
                      onPressed: () {
                        NavigationHelper.navigatetoBspsignupcreen(context);
                      },
                    ),
                  ],
                )
              ],
            ),
          ),
          actions: <Widget>[
            FlatButton(
              child: Text('Close'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  Widget _buildClearButton() {
    return new FlatButton(
      onPressed: () {
        _email.clear();
        _fn.clear();
        _ln.clear();
        _pho.clear();
        _add.clear();
        _pass.clear();
        _isError = false;

        setState(() {
          _isError = false;
        });
      },
      child: Text(
        AppConstantsValue.appConst['signup']['clear']['translation'],
        style: TextStyle(letterSpacing: 1.5),
      ),
    );
  }

  Widget _buildSignupButton(SignupBloc signupBloc, BuildContext context) {
    return GestureDetector(
      child: RoundrectButton.buildRoundedRectButton(
          AppConstantsValue.appConst['signup']['signup']['translation'],
          signUpGradients,
          false),
      onTap: () {
        //  _submit();
        final FormState form = formKey.currentState;
        form.save();
        if (form.validate() && person.termsAndCondition) {
          setState(() {
            _isLoading = true;
          });
          Map<String, dynamic> signupdata = {
            'email': person.email,
            'country': person.country,
            'countyCode': person.countryCode,
            'phoneNumber': person.phoneNumber,
            'firstName': person.firstname,
            'lastName': person.lastname,
            'password': person.password,
          };
          _isError
              ? new Container(child: Text("Error"))
              : widget._signupBloc.dispatch(
                  SignupButtonClickedEvent(signupdata: signupdata),
                );
        } else {
          print("Toast is printed");
          Errortoast().showColoredToast();
          setState(() {
            _isLoading = false;
            _validate = true;
          });
        }
      },
    );
  }

  Widget _buildBackButton(BuildContext context) {
    return FlatButton(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Icon(Icons.arrow_back_ios),
          Text(AppConstantsValue.appConst['signup']['backtologin']
              ['translation'])
        ],
      ),
      onPressed: () => Navigator.pop(context, false),
    );
  }

  Widget _buildLoader() {
    return Loader(
      color: colorStyles["primary"],
    );
  }

  Widget content(signupBloc, context, List<Country> countries) {
    return SafeArea(
      top: false,
      bottom: false,
      child: Form(
        key: formKey,
        autovalidate: _validate,
        child: Scrollbar(
          child: SingleChildScrollView(
            dragStartBehavior: DragStartBehavior.down,
            padding: const EdgeInsets.symmetric(horizontal: 16.0),
            child: new Container(
              margin: EdgeInsets.fromLTRB(30, 0, 30, 0),
              child: new Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  _buildLogo(),
                  _buildEmailField(),
                  _buildCountry(countries),
                  _buildPhonefiled(),
                  _buildFnamefiled(),
                  _buildLnamefiled(),
                  _buildPasswordfiled(),
                  _buildTermsAndContionsCheck(),
                  SizedBox(),
                  _isError ? new Text('Fail to signup') : SizedBox(),
                  _isLoading ? _buildLoader() : SizedBox(),
                  _buildClearButton(),
                  _buildSignupButton(signupBloc, context),
                  _buildBackButton(context),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<SignupBloc, SignupState>(
      bloc: widget._signupBloc,
      builder: (
        BuildContext context,
        SignupState currentState,
      ) {
        if (currentState is UnSignupState) {
          return Container(
            height: MediaQuery.of(context).size.height / 1.10,
            width: MediaQuery.of(context).size.width / 1.10,
            child: Center(
              child: _buildLoader(),
            ),
          );
        }

        if (currentState is ErrorSignupState) {
          _isLoading = false;
          _isError = true;
          showAlertBox = false;
          return Container(
            child: content(_signupBloc, context, _countries),
          );
        }
        if (currentState is InSignupState) {
          _countries = currentState.countries.countries;
          return Container(child: content(_signupBloc, context, _countries));
        }

        if (currentState is SignupButtonClickedEvent) {
          print('SignupButtonClickedEvent clicked');
          return Container();
        }

        if (currentState is SignupSuccessState) {
          print(
              ' You are awesome. you have successfully registered without confirmation');
          print(currentState.signupUser.toJson());
          print("Hey Otp Is opned");
          WidgetsBinding.instance.addPostFrameCallback((_) {
            // _never();

            _onAlertotp();
          });
          _isLoading = false;
          showAlertBox = true;
          return Container(
            child: content(_signupBloc, context, _countries),
          );
        }

        if (currentState is SignupVerficationOtp) {
          print('signup verficitaion otp button clicked');
          return Container();
        }
        return Container(child: content(_signupBloc, context, _countries));
      },
    );
  }
}

class Person {
  String email = '';
  String country = '';
  String countryCode = '';
  String phoneNumber = '';
  String firstname = '';
  String lastname = '';
  String password = '';
  bool termsAndCondition = false;
}

class CountryModel {
  String country = '';
  String countryCode = '';

  CountryModel({
    this.country,
    this.countryCode,
  });
}

Body:
First of all if you are using Bloc Pattern you can't use setState. Other thing is you should make a new class for a bloc. In your case RegistrationBloc. Then Import RxDart.

class SignupBloc{

String _nameValue;

BehaviourSubject<String> _nameSubject = BehaviourSubject<String>();
Stream<String> get nameStream => _nameSubject.stream;
StreamController<String> _name = StreamController<String>();
Sink<String> get nameSink => _name.sink;

SignupBloc(){

   //Inside the StreamController you can do anything to your value
   _name.stream.listen((name){
      if(name == "" || name == null){
         _nameSubject.addError("Please Enter Your Name");
      }else{
         _nameValue = name;
      }
   }
}

Make sure you firs create and Instance of Your Bloc

SignUpBloc _signUpBloc = SignInBloc();

Your Text Field Should Be like this

StreamBuilder<String>(
  stream: _signUpBloc.nameStream,
  builder: (context, snapshot) {
    return TextField(
      onChanged: (value) => _signUpBloc.nameSink.add(value),
      decoration: InputDecoration(
          labelText: "label", errorText: snapshot.error),
    );
  }
);


来源: stackexchange

问:
Making python wait until subprocess.call has finished its command
So this question is following on from this (Read comments aswell as that is the path I took). I just want the first call robocopy to finish executing before moving on to the rest of the code. As I want the second robocopy to just skip all of the files as they have already been copied over. However what is happening is that the rest of the script will run (ie starts the second robocopy) while the first robocopy is copying over the files. Below is the code:

```<code>call(["start", "cmd", "/K", "RoboCopy.exe", f"{self.srcEntry.get()}", f"{self.dstEntry.get()}", "*.*", "/E", "/Z", "/MT:8"], stdout=PIPE, shell=True)
temp2 = Popen(["RoboCopy.exe", f"{self.srcEntry.get()}", f"{self.dstEntry.get()}", "*.*", "/E", "/Z"], stdout=PIPE, stdin=PIPE, shell=True)
</code>```

EDIT 1:

Issue is noticeable when copying over large files. I'm thinking about putting in a sleep function which is dependent upon the total size of the files to be copied over. However this doesn't take into account upload/download speeds as the files will be transferred over a network.

答:
I use the following function to launch my commands which waits until the action has finished, but has a timeout:

import os
import logging

logger = logging.getLogger()

def command_runner(command, valid_exit_codes=None, timeout=30, shell=False, decoder='utf-8'):
    """
    command_runner 2019103101
    Whenever we can, we need to avoid shell=True in order to preseve better security
    Runs system command, returns exit code and stdout/stderr output, and logs output on error
    valid_exit_codes is a list of codes that don't trigger an error
    """

    try:
        # universal_newlines=True makes netstat command fail under windows
        # timeout does not work under Python 2.7 with subprocess32 < 3.5
        # decoder may be unicode_escape for dos commands or utf-8 for powershell
        if sys.version_info >= (3, 0):
            output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=shell,
                                             timeout=timeout, universal_newlines=False)
        else:
            output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=shell,
                                             universal_newlines=False)
        output = output.decode(decoder, errors='backslashreplace')
    except subprocess.CalledProcessError as exc:
        exit_code = exc.returncode
        # noinspection PyBroadException
        try:
            output = exc.output
            try:
                output = output.decode(decoder, errors='backslashreplace')
            except Exception as subexc:
                logger.debug(subexc, exc_info=True)
                logger.debug('Cannot properly decode error. Text is %s' % output)
        except Exception:
            output = "command_runner: Could not obtain output from command."
        if exit_code in valid_exit_codes if valid_exit_codes is not None else [0]:
            logger.debug('Command [%s] returned with exit code [%s]. Command output was:' % (command, exit_code))
            if output:
                logger.debug(output)
            return exc.returncode, output
        else:
            logger.error('Command [%s] failed with exit code [%s]. Command output was:' %
                         (command, exc.returncode))
            logger.error(output)
            return exc.returncode, output
    # OSError if not a valid executable
    except OSError as exc:
        logger.error('Command [%s] faild because of OS [%s].' % (command, exc))
        return None, exc
    except subprocess.TimeoutExpired:
        logger.error('Timeout [%s seconds] expired for command [%s] execution.' % (timeout, command))
        return None, 'Timeout of %s seconds expired.' % timeout
    except Exception as exc:
        logger.error('Command [%s] failed for unknown reasons [%s].' % (command, exc))
        logger.debug('Error:', exc_info=True)
        return None, exc
    else:
        logger.debug('Command [%s] returned with exit code [0]. Command output was:' % command)
        if output:
            logger.debug(output)
        return 0, output

# YOUR CODE HERE

executable = os.path.join(os.environ['SYSTEMROOT'], 'system32', 'robocopy.exe')
mycommand = '"%s" "%s" "%s" "%s"' % (executable, source, dest, options)
result, output = command_runner(mycommand, shell=True)

```

ContentLicense: CC BY-SA 4.0

Body:
So this question is following on from this (Read comments aswell as that is the path I took). I just want the first call robocopy to finish executing before moving on to the rest of the code. As I want the second robocopy to just skip all of the files as they have already been copied over. However what is happening is that the rest of the script will run (ie starts the second robocopy) while the first robocopy is copying over the files. Below is the code:

call(["start", "cmd", "/K", "RoboCopy.exe", f"{self.srcEntry.get()}", f"{self.dstEntry.get()}", "*.*", "/E", "/Z", "/MT:8"], stdout=PIPE, shell=True)
temp2 = Popen(["RoboCopy.exe", f"{self.srcEntry.get()}", f"{self.dstEntry.get()}", "*.*", "/E", "/Z"], stdout=PIPE, stdin=PIPE, shell=True)

EDIT 1:

Issue is noticeable when copying over large files. I'm thinking about putting in a sleep function which is dependent upon the total size of the files to be copied over. However this doesn't take into account upload/download speeds as the files will be transferred over a network.


问:
What should be the proper commands for pushing a web app via ibmcloud?
I want 2 deploy a simple laravel app via ibmcloud but I was really having a hard time trying to figure out this crazy workflow. So, the steps that I've done is like this

```<code>$ ibmcloud login

</code>```

Then what should follow ?

I already did it like this

答:
As I see manifest.yml file, I am assuming that you are planning to push your app to Cloud Foundry on IBM Cloud. The next steps will be to specify an Org and space interactively

```<code>ibmcloud target --cf
</code>```

Or, if you know which org and space that the service belongs to, you can use the following command:

```<code>ibmcloud target -o <value> -s <value>
</code>```

Once specified, deploy your app to IBM Cloud by using the following command

```<code>ibmcloud cf push
</code>```

For more information on modifying and redeploying your Cloud Foundry app with the command-line interface, refer this link

Body:
I want 2 deploy a simple laravel app via ibmcloud but I was really having a hard time trying to figure out this crazy workflow. So, the steps that I've done is like this

$ ibmcloud login

Then what should follow ?

I already did it like this

Body:
As I see manifest.yml file, I am assuming that you are planning to push your app to Cloud Foundry on IBM Cloud. The next steps will be to specify an Org and space interactively

ibmcloud target --cf

Or, if you know which org and space that the service belongs to, you can use the following command:

ibmcloud target -o <value> -s <value>

Once specified, deploy your app to IBM Cloud by using the following command

ibmcloud cf push

For more information on modifying and redeploying your Cloud Foundry app with the command-line interface, refer this link


问:
How to Return Files (PDF) From asp.net web api 2
I would like to get pdf file from asp.net web api 2 / c#

here is my Controller

```<code>[JwtAuthentication]
[HttpGet]
[Route("Document")]
public IHttpActionResult GetDocument([FromUri]int IdDocument, [FromUri]int ContentFileType)
{
    string filePath = "C:\\xxxxxxxxx\\pdf\\14076186.pdf";
    if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath) || IdDocument == 0)
    {
        return NotFound();
    }

    if (ContentFileType == 0 || ContentFileType == 4)
    {
        byte[] dataBytes = File.ReadAllBytes(filePath);
        MemoryStream pdfDataStream = new MemoryStream(dataBytes);
        string pdfName = IdDocument + "pdf";
        return new PdfResult(pdfDataStream, Request, pdfName);
    }
    else
    {
        HttpResponseMessage responseMsg = new HttpResponseMessage(HttpStatusCode.OK);
        responseMsg.Content = new StreamContent(new FileStream(filePath, FileMode.Open, FileAccess.Read));
        return ResponseMessage(responseMsg);
    }
}
</code>```

here is my PdfResult class

```<code>public class PdfResult : IHttpActionResult
{
    private readonly MemoryStream PdfStuff;
    private readonly string PdfFileName;
    private readonly HttpRequestMessage httpRequestMessage;
    private HttpResponseMessage httpResponseMessage;

    public PdfResult(MemoryStream data, HttpRequestMessage request, string filename)
    {
        PdfStuff = data;
        httpRequestMessage = request;
        PdfFileName = filename;
    }
    public System.Threading.Tasks.Task<HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken)
    {
        httpResponseMessage = httpRequestMessage.CreateResponse(HttpStatusCode.OK);
        httpResponseMessage.Content = new StreamContent(PdfStuff);
        //httpResponseMessage.Content = new ByteArrayContent(PdfStuff.ToArray());
        httpResponseMessage.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
        httpResponseMessage.Content.Headers.ContentDisposition.FileName = PdfFileName;
        httpResponseMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); // application/pdf
        return System.Threading.Tasks.Task.FromResult(httpResponseMessage);
    }
}
</code>```

and when i run this on postman i get this (I have GZip Compression enabled)

{{url}}/document?idDocument=14076186&contentFileType=0

```<code>%PDF-1.3
1 0 obj
[/PDF /Text /ImageB /ImageC /ImageI
]
endobj
15 0 obj
<< /Length 3306 /Filter /FlateDecode >> stream
X   �Z�R����U��gm���R��/��0d�
�!f��x.X3`{�&����[�;�-�f$`Į�OO����������,ei�2���0+t�3�ʂ��f��&�:��
    ]~d.qR1�$�Vmy�S˄J�4���#�q�d�3��D    ø_�1�ne|�3��w����?`�G��
n���Eb�c��@Ɓ�l0b;{�QY,�����
����    �f�Rp���hv��    ����@wĲD`��tB6ŉqrc��    ����iH(�B\k �I��d��萣R�J�je;I�)�%.����R��X�v��&�+���n�X��v�3e.�v6Q nM��e`����b�6Ê�։"�W,e_�<�d\"S�Y~��ϊ�X����5X�^,�J,�P��V8�Q��Q�pL��UeS���됙!�L+����4wj���ښ��D��1k>U���f������������E1Y��|�|\�h�Z�n?+,��p��(�!��8�h��.K?�Z!�2��:cB<�Z�&&���c&������o�������2Χ-�J�DXd�<k�\�l���)��(����MO�Kv�,�O[\u
�f��*��{s�d��M�>��\H�(N&�L���W�K����3&�Vr�nM�'oneDC�je;*�����d�V6����^e��Y
        ]��H�x�jKx�i� ��x�f�{��?�{xܳuŖ���ڽϋEQ>���|�r��#���b��ʡBk�!�sq���Rl�
            }�%*k�;=y��m��T
�β'pPs��a�Wj�yE������jgq���g7�r���h
�<YT���
</code>```

Can any one help me please ?

答:
Your response already looks like it is a PDF.

Can you try saving the response from 'Save Response' -> 'Save to a file' from the Postman?

Save the file with .pdf extension.

Body:
I would like to get pdf file from asp.net web api 2 / c#

here is my Controller

[JwtAuthentication]
[HttpGet]
[Route("Document")]
public IHttpActionResult GetDocument([FromUri]int IdDocument, [FromUri]int ContentFileType)
{
    string filePath = "C:\\xxxxxxxxx\\pdf\\14076186.pdf";
    if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath) || IdDocument == 0)
    {
        return NotFound();
    }

    if (ContentFileType == 0 || ContentFileType == 4)
    {
        byte[] dataBytes = File.ReadAllBytes(filePath);
        MemoryStream pdfDataStream = new MemoryStream(dataBytes);
        string pdfName = IdDocument + "pdf";
        return new PdfResult(pdfDataStream, Request, pdfName);
    }
    else
    {
        HttpResponseMessage responseMsg = new HttpResponseMessage(HttpStatusCode.OK);
        responseMsg.Content = new StreamContent(new FileStream(filePath, FileMode.Open, FileAccess.Read));
        return ResponseMessage(responseMsg);
    }
}

here is my PdfResult class

public class PdfResult : IHttpActionResult
{
    private readonly MemoryStream PdfStuff;
    private readonly string PdfFileName;
    private readonly HttpRequestMessage httpRequestMessage;
    private HttpResponseMessage httpResponseMessage;

    public PdfResult(MemoryStream data, HttpRequestMessage request, string filename)
    {
        PdfStuff = data;
        httpRequestMessage = request;
        PdfFileName = filename;
    }
    public System.Threading.Tasks.Task<HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken)
    {
        httpResponseMessage = httpRequestMessage.CreateResponse(HttpStatusCode.OK);
        httpResponseMessage.Content = new StreamContent(PdfStuff);
        //httpResponseMessage.Content = new ByteArrayContent(PdfStuff.ToArray());
        httpResponseMessage.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
        httpResponseMessage.Content.Headers.ContentDisposition.FileName = PdfFileName;
        httpResponseMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); // application/pdf
        return System.Threading.Tasks.Task.FromResult(httpResponseMessage);
    }
}

and when i run this on postman i get this (I have GZip Compression enabled)

{{url}}/document?idDocument=14076186&contentFileType=0

%PDF-1.3
1 0 obj
[/PDF /Text /ImageB /ImageC /ImageI
]
endobj
15 0 obj
<< /Length 3306 /Filter /FlateDecode >> stream
X   �Z�R����U��gm���R��/��0d�
�!f��x.X3`{�&����[�;�-�f$`Į�OO����������,ei�2���0+t�3�ʂ��f��&�:��
    ]~d.qR1�$�Vmy�S˄J�4���#�q�d�3��D    ø_�1�ne|�3��w����?`�G��
n���Eb�c��@Ɓ�l0b;{�QY,�����
����    �f�Rp���hv��    ����@wĲD`��tB6ŉqrc��    ����iH(�B\k �I��d��萣R�J�je;I�)�%.����R��X�v��&�+���n�X��v�3e.�v6Q nM��e`����b�6Ê�։"�W,e_�<�d\"S�Y~��ϊ�X����5X�^,�J,�P��V8�Q��Q�pL��UeS���됙!�L+����4wj���ښ��D��1k>U���f������������E1Y��|�|\�h�Z�n?+,��p��(�!��8�h��.K?�Z!�2��:cB<�Z�&&���c&������o�������2Χ-�J�DXd�<k�\�l���)��(����MO�Kv�,�O[\u
�f��*��{s�d��M�>��\H�(N&�L���W�K����3&�Vr�nM�'oneDC�je;*�����d�V6����^e��Y
        ]��H�x�jKx�i� ��x�f�{��?�{xܳuŖ���ڽϋEQ>���|�r��#���b��ʡBk�!�sq���Rl�
            }�%*k�;=y��m��T
�β'pPs��a�Wj�yE������jgq���g7�r���h
�<YT���

Can any one help me please ?


问:
Create DockerFile from repository
I dont know if it's possible to create a DockerFile from an existing private repository. I created a container and installed an configured the server (i dont remember all the commands), so now I want it to be syncronized with my GitHub account so whenever I push in the branch it updates the changes in the image as well.

For the automatic builds it says that I need a DockerFile but I never created one. Is there an option to automatically create a dockerfile from an exisitng image/container. Using the docker history command doesnt help much because I made the server configurations using docker exec.

Is it possible?

Thanks in advance.

答:
I'm not sure if I get the exact question but here an example for multi stage docker build (build is dockerized itself) + a temp dependency stage (better layer cleanup) for a typescript example based on existing node.js images. </p>

```<code>FROM node:12 AS build        # this could be ANY base image you want.
WORKDIR /app
COPY package*.json .npmrc ./
RUN npm i
COPY . .
RUN npm run build

FROM node:12 AS deps
WORKDIR /app
COPY .npmrc .
COPY package*.json ./
RUN npm install --only=production

FROM  node:12-alpine
ENV NODE_ENV production
WORKDIR /usr/src/app
COPY --from=deps /app/node_modules/ ./node_modules/
COPY --from=build /app/package.json .
COPY --from=build /app/build/src/ ./
COPY --from=build /app/build/config/ ./config/
CMD [ "node", "app.js" ]
</code>```

Title: Create DockerFile from repository

Body:
I'm not sure if I get the exact question but here an example for multi stage docker build (build is dockerized itself) + a temp dependency stage (better layer cleanup) for a typescript example based on existing node.js images.

FROM node:12 AS build        # this could be ANY base image you want.
WORKDIR /app
COPY package*.json .npmrc ./
RUN npm i
COPY . .
RUN npm run build

FROM node:12 AS deps
WORKDIR /app
COPY .npmrc .
COPY package*.json ./
RUN npm install --only=production

FROM  node:12-alpine
ENV NODE_ENV production
WORKDIR /usr/src/app
COPY --from=deps /app/node_modules/ ./node_modules/
COPY --from=build /app/package.json .
COPY --from=build /app/build/src/ ./
COPY --from=build /app/build/config/ ./config/
CMD [ "node", "app.js" ]


问:
Returns without a "return" command

C programming language, compiled with gcc, terminal bash in WSL

I have written a recursive function, to find the lowest number in an array, which works just fine.

```<code>/*01*/    int minimo(int array[], int n)
/*02*/    {
/*03*/      static int min = 0;
/*04*/
/*05*/      if (n == N)
/*06*/      {
/*07*/          return array[n-1];
/*08*/      }
/*09*/      else
/*10*/      {
/*11*/          min = minimo(array, n+1);
/*12*/          if(array[n]<min){
/*13*/              min = array[n];
/*14*/          }
/*15*/      }
/*16*/    }
</code>```

The only problem is that it shouldn't work, because it doesn't return "min" to the caller...

```<code>int main()
{
    //Var
    int array[N] = {10, 2, 5, 1, 7};
    printf("Min: %d\n", minimo(array, 0));
}
</code>```

My concern is actually a problem, but not on my machine onto which the function works just fine as it is;
it is a problem on my friends' laptops and IDEs, I tried copying to XCode on a friend's Macbook and it wouldn't work if the line "return min;" wasn't added at the end of the function.

Between line 15-16 I have to add return min;

```<code>/*15*/      }
            return min;
/*16*/    }
</code>```

My questions for you are the following:

How can  a function return a variable automatically?

Is it possible that it does return the only variable that I created (static int min)?

Or is it a "problem" related to the static attribute that the variable has?

Does it have anything to do with the nature of the function (recursive)?

This is my first post, please be kind if I'm breaking any forum rule.

答:
How can a function return a variable automatically?

I happens by chance, min variable happens to be in the correct return register for the ABI.

Is it possible that it does return the only variable that I created (static int min)?

I think it is more related to it having being used just before function exit, but I am guessing here: this is not a C language defined behavior, and it worked by chance.

Or is it a "problem" related to the static attribute that the variable has?

Does it have anything to do with the nature of the function (recursive)?

Since this was a chance behavior, could be or not. The difference between random and deterministic is that you have so many variables that you give up explaining.

Title: Returns without a "return" command

Body:
C programming language, compiled with gcc, terminal bash in WSL

I have written a recursive function, to find the lowest number in an array, which works just fine.

/*01*/    int minimo(int array[], int n)
/*02*/    {
/*03*/      static int min = 0;
/*04*/
/*05*/      if (n == N)
/*06*/      {
/*07*/          return array[n-1];
/*08*/      }
/*09*/      else
/*10*/      {
/*11*/          min = minimo(array, n+1);
/*12*/          if(array[n]<min){
/*13*/              min = array[n];
/*14*/          }
/*15*/      }
/*16*/    }

The only problem is that it shouldn't work, because it doesn't return "min" to the caller...

int main()
{
    //Var
    int array[N] = {10, 2, 5, 1, 7};
    printf("Min: %d\n", minimo(array, 0));
}

My concern is actually a problem, but not on my machine onto which the function works just fine as it is;
it is a problem on my friends' laptops and IDEs, I tried copying to XCode on a friend's Macbook and it wouldn't work if the line "return min;" wasn't added at the end of the function.

Between line 15-16 I have to add return min;

/*15*/      }
            return min;
/*16*/    }

My questions for you are the following:

How can  a function return a variable automatically?

Is it possible that it does return the only variable that I created (static int min)?

Or is it a "problem" related to the static attribute that the variable has?

Does it have anything to do with the nature of the function (recursive)?

This is my first post, please be kind if I'm breaking any forum rule.


问:
DataList in Angular
I have a <datalist> and <select> as follows:

Updated:

Example 1:

```<code><input type="text"  list="codes" [(ngModel)]="codeValue" (change)="saveCode(codeValue)">
<datalist id="codes">
  <option *ngFor="let c of codeList" [value]="c.code" >{{c.name}}</option>
</datalist>

<select type="text"  list="codes" [(ngModel)]="codeValue1" (change)="saveCode(codeValue)">
  <option *ngFor="let c of codeList" [value]="c.code" >{{c.name}}</option>
</select>
</code>```

codeList Array in component.ts

```<code>    codeList = [
    { code: 'abcdhe568dhjkldn', name: 'item1' },
    { code: 'ksdkcs7238t8cds', name: 'item2' },
    { code: 'kascggibebbi', name: 'item3' }
  ];
</code>```

DataList is showing both name (c.name) and value (c.code) in the options and storing whatever is present in value whereas select is showing name (c.name) and storing value(c.code).

Behavior of datalist

<img src="https://i.stack.imgur.com/u5qBQ.png" alt="Behavior of <dataList>">

Behavior of select

<img src="https://i.stack.imgur.com/uuQZ2.png" alt="Behavior of <select>">

Example 2:

```<code><datalist id="codes">
<option *ngFor = "let i of [1,2,3,4]" [value]="i">{{i-1}}</option>
</datalist>

{{a}}
</code>```

I want to show the value of i-1 in the suggestion box but bind the variable 'a' with i.

Existing Solution in HTML

From this post Show datalist labels but submit the actual value I see that we can use "data-value" to
acheive the functionality in HTML. How can I achieve the same functionality in Angular.

Please help!

Thanks in advance.

答:
Try Like this....

html File

```<code><input type="text"  list="codes" [(ngModel)]="codeValue" (change)="saveCode($event)">
<datalist id="codes">
<option *ngFor="let c of codeList" [value]="c.name" >{{c.name}}</option>
</datalist>
</code>```

ts File

```<code> codeList = [
{ code: 'abcdhe568dhjkldn', name: 'item1' },
{ code: 'ksdkcs7238t8cds', name: 'item2' },
{ code: 'kascggibebbi', name: 'item3' }
];

 public saveCode(e): void {
let name = e.target.value;
let list = this.codeList.filter(x => x.name === name)[0];
console.log(list.id);
}
</code>```

ContentLicense: CC BY-SA 3.0

Title: DataList in Angular

Body:
I have a <datalist> and <select> as follows:

Updated:

Example 1:

<input type="text"  list="codes" [(ngModel)]="codeValue" (change)="saveCode(codeValue)">
<datalist id="codes">
  <option *ngFor="let c of codeList" [value]="c.code" >{{c.name}}</option>
</datalist>

<select type="text"  list="codes" [(ngModel)]="codeValue1" (change)="saveCode(codeValue)">
  <option *ngFor="let c of codeList" [value]="c.code" >{{c.name}}</option>
</select>

codeList Array in component.ts

    codeList = [
    { code: 'abcdhe568dhjkldn', name: 'item1' },
    { code: 'ksdkcs7238t8cds', name: 'item2' },
    { code: 'kascggibebbi', name: 'item3' }
  ];

DataList is showing both name (c.name) and value (c.code) in the options and storing whatever is present in value whereas select is showing name (c.name) and storing value(c.code).

Behavior of datalist

<img src="https://i.stack.imgur.com/u5qBQ.png" alt="Behavior of <dataList>">

Behavior of select

<img src="https://i.stack.imgur.com/uuQZ2.png" alt="Behavior of <select>">

Example 2:

<datalist id="codes">
<option *ngFor = "let i of [1,2,3,4]" [value]="i">{{i-1}}</option>
</datalist>

{{a}}

I want to show the value of i-1 in the suggestion box but bind the variable 'a' with i.

Existing Solution in HTML

From this post Show datalist labels but submit the actual value I see that we can use "data-value" to
acheive the functionality in HTML. How can I achieve the same functionality in Angular.

Please help!

Thanks in advance.

Body:
Try Like this....

html File

<input type="text"  list="codes" [(ngModel)]="codeValue" (change)="saveCode($event)">
<datalist id="codes">
<option *ngFor="let c of codeList" [value]="c.name" >{{c.name}}</option>
</datalist>

ts File

 codeList = [
{ code: 'abcdhe568dhjkldn', name: 'item1' },
{ code: 'ksdkcs7238t8cds', name: 'item2' },
{ code: 'kascggibebbi', name: 'item3' }
];

 public saveCode(e): void {
let name = e.target.value;
let list = this.codeList.filter(x => x.name === name)[0];
console.log(list.id);
}


问:
ionic 4 ng-true-value equivalence
I'm rewriting an ionic 1 app to ionic 4.5.0, and i have a calculator like this in ionic 1:

HTML:

```<code>    <ion-toggle toggle-class="toggle-positive" id="myid" ng-model="data.product1" ng-false-value="0" ng-true-value="50">{{data.product1}}
      <i class="icon ion-social-euro"></i>
    </ion-toggle>
</code>```

ControllerJs:

```<code>$scope.data = {
    'product1' : 0,
    'product2' : 0,
    'product3' : 0
}
</code>```

On ionic 1 we had directives like:

ng-false-value="0" ng-true-value="50"

so, when toggle were on, the true value were 50, and false 0.

On my new app, i'm trying to do the same:

HTML:

```<code>   <ion-item>
      <ion-label>Product 1 {{data.product1}}</ion-label>
      <ion-toggle name="product1" [(ngModel)]="data.product1"></ion-toggle>
    </ion-item>
</code>```

ts

```<code>data: any = {
    product1: 0,
    product2: 0,
    product3: 0
};
</code>```

{{data.product1}} is showing 0, but when i activate the toggle it's showing true or false

I have found this solution, but it's for angular: https://juristr.com/blog/2018/02/ng-true-value-directive/

Is there any equivalent or something else for ng-true-value and ng-false-value in ionic 4?

答:
One approach is to use the ionChange event to add/subtract 50 when the toggle changes value.

In this example we are passing the product key of the data object, and the toggled value. This way you can reuse the function.

<ion-item>
  <ion-label>Product 1 {{data.product1}}</ion-label>
  <ion-toggle name="product1" [(ngModel)]="toggle.product1" (ionChange)="toggleValues('product1', 50)"></ion-toggle>
</ion-item>
```

<pre class="lang-js prettyprint-override"><code>toggle = {
  'product1': false;
  // add more
}

toggle50Values(productKey: string, value: number) {
  if (this.toggle[productKey]) {   // toggle is true
    this.data[productKey] += value;
  } else {                         // toggle is false
    this.data[productName] -= value;
  }
}
</code>```

Documentation: Ion-toggle

Title: ionic 4 ng-true-value equivalence

Body:
I'm rewriting an ionic 1 app to ionic 4.5.0, and i have a calculator like this in ionic 1:

HTML:

    <ion-toggle toggle-class="toggle-positive" id="myid" ng-model="data.product1" ng-false-value="0" ng-true-value="50">{{data.product1}}

    </ion-toggle>

ControllerJs:

$scope.data = {
    'product1' : 0,
    'product2' : 0,
    'product3' : 0
}

On ionic 1 we had directives like:

ng-false-value="0" ng-true-value="50"

so, when toggle were on, the true value were 50, and false 0.

On my new app, i'm trying to do the same:

HTML:

   <ion-item>
      <ion-label>Product 1 {{data.product1}}</ion-label>
      <ion-toggle name="product1" [(ngModel)]="data.product1"></ion-toggle>
    </ion-item>

ts

data: any = {
    product1: 0,
    product2: 0,
    product3: 0
};

{{data.product1}} is showing 0, but when i activate the toggle it's showing true or false

I have found this solution, but it's for angular: https://juristr.com/blog/2018/02/ng-true-value-directive/

Is there any equivalent or something else for ng-true-value and ng-false-value in ionic 4?

Body:
One approach is to use the ionChange event to add/subtract 50 when the toggle changes value.

In this example we are passing the product key of the data object, and the toggled value. This way you can reuse the function.

<ion-item>
  <ion-label>Product 1 {{data.product1}}</ion-label>
  <ion-toggle name="product1" [(ngModel)]="toggle.product1" (ionChange)="toggleValues('product1', 50)"></ion-toggle>
</ion-item>

toggle = {
  'product1': false;
  // add more
}

toggle50Values(productKey: string, value: number) {
  if (this.toggle[productKey]) {   // toggle is true
    this.data[productKey] += value;
  } else {                         // toggle is false
    this.data[productName] -= value;
  }
}

Documentation: Ion-toggle


问:
Laravel view foreach with two properties
i need help with my foreach loop in view

Controller.php

```<code>$expenses = Expense::groupBy('category_id')->selectRaw('sum(amount) as sum, category_id')->pluck('sum','category_id');

$categories = Category::all();

return view('dashboard.index', compact('expenses','categories'));
</code>```

index.php

```<code>          <table class="table">
            <thead>
              <th>Category</th>
              <th>Expenses</th>
            </thead>
            <tbody>
              @foreach($categories as $category)
              <tr>
                <td>{{ $category->name }}</td>
                @foreach($expenses as $expense)
              <td>{{ $expense }}</td>
              @endforeach
              </tr>
              @endforeach
            </tbody>
          </table>
</code>```

I get the output like this.

enter image description here

It outputs the expense 2 times, is there a limiter for "foreach loop" or is there another way on doing this?

答:
You should compare category_id with category->id.

```<code>@foreach($categories as $category)
<tr>
    <td>{{ $category->name }}</td>
    @foreach($expenses as $expense)
        @if($expense->category_id == $category->id )
            <td>{{ $expense->sum }}</td>
        @endif
    @endforeach
</tr>
@endforeach
</code>```

Body:
i need help with my foreach loop in view

Controller.php

$expenses = Expense::groupBy('category_id')->selectRaw('sum(amount) as sum, category_id')->pluck('sum','category_id');

$categories = Category::all();

return view('dashboard.index', compact('expenses','categories'));

index.php

              Category
              Expenses

              @foreach($categories as $category)

                {{ $category->name }}
                @foreach($expenses as $expense)
              {{ $expense }}
              @endforeach

              @endforeach

I get the output like this.

enter image description here

It outputs the expense 2 times, is there a limiter for "foreach loop" or is there another way on doing this?

Body:
You should compare category_id with category->id.

@foreach($categories as $category)
<tr>
    <td>{{ $category->name }}</td>
    @foreach($expenses as $expense)
        @if($expense->category_id == $category->id )
            <td>{{ $expense->sum }}</td>
        @endif
    @endforeach
</tr>
@endforeach


问:
Device context size is getting reduced during drawing sometimes
We have an application in MFC.

We have come across an issue with device context.
The situation is like - we have an info display window, which is variable in size and posiion.
During some size and position changing scenarios, only part of the window is drawn, like a portion of the window is cut.

We doubted there is difference between the rect in device context and the rect returned from GetWindowRect function.
So we have logged and checked the size of the window rect which is being drawn from the device context and also
the window rect of memory DC which is used for drawing during the issue scenario.

But both returned the small window rect size.
That is device context has only the partial information of the rect at that time.

We didn't called UpdateWindow() or Invalidate().

When we focused the window using WinSpy, the whole window is present, but only that small portion is drawn.

We placed and then removed another window above this window to check whether any repainting would happen. But still the issue persists.

Can anyone please help rectify this problem?

hi, our code is like this.

                                                                                BOOL InfoDisplayWindow::OnEraseBkgnd(CDC* pDC)
{

```<code>CBitmap m_bitmap; // Offscreen bitmap
CBitmap* m_oldBitmap; // bitmap originally found
CRect m_rect; // Rectangle of drawing area.

HDC hDC = CreateCompatibleDC(pDC->m_hDC);
CDC* pTmpDC = CDC::FromHandle(hDC);
pDC->GetClipBox(&m_rect);
m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
m_oldBitmap = pTmpDC->SelectObject(&m_bitmap);
pTmpDC->SetWindowOrg(m_rect.left, m_rect.top);

CRect rc;
GetClientRect(&rc);
pTmpDC->FillSolidRect(&rc, COLOR_KEY);

DrawFunction();// Text is displayed in this function

CPen pen(PS_SOLID, SOLID_BORDER_WIDTH, BORDER_COLOR);
CPen *old_pen = pTmpDC->SelectObject(&pen);

// Drawing the 4 boarders of the window here.
pTmpDC->MoveTo(rc.left, rc.bottom - 1);
pTmpDC->LineTo(rc.left, rc.top);
pTmpDC->LineTo(rc.right - 1, rc.top);
pTmpDC->LineTo(rc.right - 1, rc.bottom - 1);
pTmpDC->LineTo(rc.left, rc.bottom - 1);
pTmpDC->SelectObject(old_pen);

// Copy the offscreen bitmap onto the screen.
pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
  pTmpDC, m_rect.left, m_rect.top, SRCCOPY);
//Swap back the original bitmap.
pTmpDC->SelectObject(m_oldBitmap);

return TRUE;
</code>```

}

答:
I assume you get your device context (DC) either from BeginPaint (or using MFC using a CPaintDC) or from GetDC. All these variants give you the DC for your window's client area, which doesn't include the border and title bar. The corresponding rect is returned by GetClientRect.
Corresponding to GetWindowRect is GetWindowDC, which allows to draw in the full area. Be aware that GetWindowRect gives you screen coordinates, so you should transform them by ScreenToClient before applying them to your DC.</p>

Body:
We have an application in MFC.

We have come across an issue with device context.
The situation is like - we have an info display window, which is variable in size and posiion.
During some size and position changing scenarios, only part of the window is drawn, like a portion of the window is cut.

We doubted there is difference between the rect in device context and the rect returned from GetWindowRect function.
So we have logged and checked the size of the window rect which is being drawn from the device context and also
the window rect of memory DC which is used for drawing during the issue scenario.

But both returned the small window rect size.
That is device context has only the partial information of the rect at that time.

We didn't called UpdateWindow() or Invalidate().

When we focused the window using WinSpy, the whole window is present, but only that small portion is drawn.

We placed and then removed another window above this window to check whether any repainting would happen. But still the issue persists.

Can anyone please help rectify this problem?

hi, our code is like this.

                                                                                BOOL InfoDisplayWindow::OnEraseBkgnd(CDC* pDC)
{

CBitmap m_bitmap; // Offscreen bitmap
CBitmap* m_oldBitmap; // bitmap originally found
CRect m_rect; // Rectangle of drawing area.

HDC hDC = CreateCompatibleDC(pDC->m_hDC);
CDC* pTmpDC = CDC::FromHandle(hDC);
pDC->GetClipBox(&m_rect);
m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
m_oldBitmap = pTmpDC->SelectObject(&m_bitmap);
pTmpDC->SetWindowOrg(m_rect.left, m_rect.top);

CRect rc;
GetClientRect(&rc);
pTmpDC->FillSolidRect(&rc, COLOR_KEY);

DrawFunction();// Text is displayed in this function

CPen pen(PS_SOLID, SOLID_BORDER_WIDTH, BORDER_COLOR);
CPen *old_pen = pTmpDC->SelectObject(&pen);

// Drawing the 4 boarders of the window here.
pTmpDC->MoveTo(rc.left, rc.bottom - 1);
pTmpDC->LineTo(rc.left, rc.top);
pTmpDC->LineTo(rc.right - 1, rc.top);
pTmpDC->LineTo(rc.right - 1, rc.bottom - 1);
pTmpDC->LineTo(rc.left, rc.bottom - 1);
pTmpDC->SelectObject(old_pen);

// Copy the offscreen bitmap onto the screen.
pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
  pTmpDC, m_rect.left, m_rect.top, SRCCOPY);
//Swap back the original bitmap.
pTmpDC->SelectObject(m_oldBitmap);

return TRUE;

}


问:
Add boost program_options as a git submodule and build an executable with its sources
I have a small project that uses boost::program_options. I want to add this (only this) library to my project as a git submodule and build my executable using its sources.

I have already done the git submodule part (git submodule add https://github.com/boostorg/program_options.git), and I have done a small experiment in which I build an example application using only the sources in the mentioned submodule (to double check that there are not extra dependencies).

Now I want to add these sources to my project. What I do in my CMakeLists.txt file is:

```<code>set(BOOST_PROGRAM_OPTIONS_SOURCES
  boost/program_options/src/split.cpp
  boost/program_options/src/positional_options.cpp
  boost/program_options/src/parsers.cpp
  boost/program_options/src/options_description.cpp
  boost/program_options/src/convert.cpp
  boost/program_options/src/config_file.cpp
  boost/program_options/src/cmdline.cpp
  boost/program_options/src/winmain.cpp
  boost/program_options/src/variables_map.cpp
  boost/program_options/src/value_semantic.cpp
  boost/program_options/src/utf8_codecvt_facet.cpp
)
</code>```

and

```<code>add_executable(
  ...
  src/main.cpp
  ${BOOST_PROGRAM_OPTIONS_SOURCES}
)
</code>```

but I obtain the following error:

```<code>CMake Error at CMakeLists.txt:69 (add_executable):
  The target name "boost/program_options/src/split.cpp" is reserved or not
  valid for certain CMake features, such as generator expressions, and may
  result in undefined behavior.

CMake Error at CMakeLists.txt:86 (target_link_libraries):
  Cannot specify link libraries for target "..." which is not built
  by this project.
</code>```

What is the right way to do what I want>

答:
I have found the problem.

I have cloned boost::program_options (git clone https://github.com/boostorg/program_options.git) in the same folder as the CMakeLists.txt

After that, following the normal FindBoost flow

```<code>set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED OFF)
set(Boost_USE_STATIC_RUNTIME OFF)

find_package(Boost 1.45.0 COMPONENTS program_options)

if(Boost_FOUND)
  message(WARNING "BOOST FOUND")
  include_directories(${Boost_INCLUDE_DIRS})
  set(BOOST_LIBS ${Boost_LIBRARIES})
else()
  set(BOOST_LIBS )
  message(WARNING "BOOST NOT FOUND")
endif()
...
...
target_link_libraries(... ${BOOST_LIBS})
...
...
</code>```

CMake is able to find boost even though program_options does not contain any CMakeLists.txt (I can't find it at least)

Body:
I have a small project that uses boost::program_options. I want to add this (only this) library to my project as a git submodule and build my executable using its sources.

I have already done the git submodule part (git submodule add https://github.com/boostorg/program_options.git), and I have done a small experiment in which I build an example application using only the sources in the mentioned submodule (to double check that there are not extra dependencies).

Now I want to add these sources to my project. What I do in my CMakeLists.txt file is:

set(BOOST_PROGRAM_OPTIONS_SOURCES
  boost/program_options/src/split.cpp
  boost/program_options/src/positional_options.cpp
  boost/program_options/src/parsers.cpp
  boost/program_options/src/options_description.cpp
  boost/program_options/src/convert.cpp
  boost/program_options/src/config_file.cpp
  boost/program_options/src/cmdline.cpp
  boost/program_options/src/winmain.cpp
  boost/program_options/src/variables_map.cpp
  boost/program_options/src/value_semantic.cpp
  boost/program_options/src/utf8_codecvt_facet.cpp
)

and

add_executable(
  ...
  src/main.cpp
  ${BOOST_PROGRAM_OPTIONS_SOURCES}
)

but I obtain the following error:

CMake Error at CMakeLists.txt:69 (add_executable):
  The target name "boost/program_options/src/split.cpp" is reserved or not
  valid for certain CMake features, such as generator expressions, and may
  result in undefined behavior.

CMake Error at CMakeLists.txt:86 (target_link_libraries):
  Cannot specify link libraries for target "..." which is not built
  by this project.

What is the right way to do what I want>

Body:
I have found the problem.

I have cloned boost::program_options (git clone https://github.com/boostorg/program_options.git) in the same folder as the CMakeLists.txt

After that, following the normal FindBoost flow

set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED OFF)
set(Boost_USE_STATIC_RUNTIME OFF)

find_package(Boost 1.45.0 COMPONENTS program_options)

if(Boost_FOUND)
  message(WARNING "BOOST FOUND")
  include_directories(${Boost_INCLUDE_DIRS})
  set(BOOST_LIBS ${Boost_LIBRARIES})
else()
  set(BOOST_LIBS )
  message(WARNING "BOOST NOT FOUND")
endif()
...
...
target_link_libraries(... ${BOOST_LIBS})
...
...

CMake is able to find boost even though program_options does not contain any CMakeLists.txt (I can't find it at least)