Search code examples
flutteremail-attachmentsmailerdynamic-list

type 'List<dynamic>' is not a subtype of type 'List<Attachment>'


I use the flutter form builder to get image with camera/gallery and then I want to attach them to an email(I use mailer for this) but when I try to send the email I get the following error:

type 'List< dynamic >' is not a subtype of type 'List< Attachment >'

enter image description here Is there I way to convert the dynamic list to attachment list?

this is my code:

I get the images using the FormBuilderImagePicker widget :

FormBuilderImagePicker(
 attribute: 'image',
 onChanged: (value) {
  _attachments.add(value);
  debugPrint('attachments: $_attachments');
},
maxImages: 3,
defaultImage:
AssetImage('assets/images/icons8-plus-64.png'),
validators: [
 FormBuilderValidators.required(),
],
),

and this is my code for sending emails:

  void sendEmailWithoutPosition(
  String name,
  String destination,
  String subject,
  String description,
  String email,
  String number,
  List<Attachment> attachments,
  BuildContext context) async {
message = Message()
  ..from = Address(username, name)
  ..recipients.add(destination)
  ..subject = ' Petiție ${subject.toString()} - aplicația e-Rădăuți'
  ..html = 'Către, ${destination.toString()} <br><br> Stimată doamnă/ Stimate domn,'
      '<br><br>Subsemnatul ${name.toString()}, vă supun atenției următoarea problemă:<br><br>'
      '$description<br><br>În conformitate cu atribuțiile pe care le aveți, vă rog să luați'
      ' măsurile ce se impun.<br><br>'
      'Prezenta sesizare reprezintă o petiție în sensul O.G. nr. 27/2002 privind activitatea de soluționare a petițiilor și '
      'a fost transmisă prin intermediul aplicației mobile e-Rădăuți, dezvoltată'
      ' de Ascociația Rădăuțiul Civic, prin funcționalitatea „Sesizează o problemă”.<br><br>'
      'Vă rog să îmi transmiteți răspunsul în termenul legal la adresa $email'
      '.<br><br>Cu stimă,<br><br>'
      '     $name<br><br>     Tel: $number/$email'
  ..attachments.addAll(attachments);
tryToSendEmail(message);
}

Future<bool> tryToSendEmail(var message) async {
final smtpServer = gmail(username, password);
try {
  final sendReport = await send(message, smtpServer);
  debugPrint('Message sent: ' + sendReport.toString());
} on MailerException catch (e) {
  print('Message not sent.');
  for (var p in e.problems) {
    print('Problem: ${p.code}: ${p.msg}');
  }
}
}

I've tried to map the list using this code:

List<Attachment> listAttachments = _attachments
                            .map((e) => e as Attachment)
                            .toList();
                        List<Attachment> listAttachmentsNew =
                            listAttachments.cast<Attachment>();

but now I get the following error: enter image description here


Solution

  • By diving deeper into the structure of the package what I suggest you is to use a constructor: attachment is an abstract class and it can't be simply casted. Depending on the type of attachment you can do:

    //FOR FILE ATTACHMENTS
    List<Attachment> listAttachments = _attachments.map((e) => FileAttachment(e.file)).toList();
    //FOR STRING ATTACHMENTS
    List<Attachment> listAttachments = _attachments.map((e) => StringAttachment(e.data)).toList();
    

    Obviously adapt the code to your data. To have a better idea of how these class are structured give a look at this page: Attachment class github reference

    Update: I gave a look into the library you are using but it lacks documentation. Insted of using onChanged try using onImage. In this way, every time you pick an image you should get the data you need.