I am trying to send some data and a file to my node js server. The file is a .txt file and I am using FilePicker to get the file and MultiPartRequest to send it.
This is the Widget with the text forms and the attachment button:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Crear una nueva tarea'),
backgroundColor: Colors.green[300],
),
body: ChangeNotifierProvider<LoginFormProvider>(
create: (context) => LoginFormProvider(),
child: Consumer<LoginFormProvider>(builder: (context, value, child) {
final loginFormProvider =
Provider.of<LoginFormProvider>(context, listen: true);
return Container(
color: Colors.grey[100],
padding: EdgeInsets.symmetric(horizontal: 20),
child: Center(
child: ConstrainedBox(
constraints: BoxConstraints(maxHeight: 370),
child: Form(
key: loginFormProvider.formKey,
child: Column(
children: [
TextFormField(
onChanged: (value) =>
loginFormProvider.title = value,
decoration: buildInputDecoration(
hint: 'Enunciado',
label: 'Enunciado de la tarea',
icon: Icons.title),
),
SizedBox(
height: 20,
),
TextFormField(
onChanged: (value) =>
loginFormProvider.date = value,
cursorColor: Colors.green,
decoration: buildInputDecoration(
hint: 'Fecha limite',
label: 'Fecha limite de entrega',
icon: Icons.date_range),
),
SizedBox(
height: 20,
),
ElevatedButton(
onPressed: () async {
final result =
await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['txt', 'docx'],
);
final file = result!.files.first.name;
value.setFile(result);
},
child: Text('Seleccionar archivo')),
SizedBox(
height: 20,
),
CustomOutlinedButton(
onPressed: () async {
if (value.file == null) return;
value.makePostRequest(loginFormProvider.title,
id, teacherID, loginFormProvider.date);
Navigator.pop(context);
},
text: 'Crear Tarea'),
],
),
),
),
));
})),
);
}
And I am trying to send the request as follows in this class:
class LoginFormProvider extends ChangeNotifier {
GlobalKey<FormState> formKey = new GlobalKey<FormState>();
var file;
String role = '';
String id = '';
String lastname = '';
String firstname = '';
String password = '';
String tid = '';
String name = '';
String title = '';
int teacherid = 0;
int subjectid = 0;
String date = '';
bool validateForm() {
if (formKey.currentState!.validate()) {
return true;
} else {
return false;
}
}
Future setFile(txt) async {
this.file = txt;
this.notifyListeners();
}
Future makePostRequest(
String title, int subjectid, int teacherid, String limitDate) async {
var url = Uri.parse('http://localhost:8000/newHomework');
var request = http.MultipartRequest('POST', url);
var headers = {'Content-Type': 'text/plain; charset=UTF-8'};
File fileByte = this.file;
Uint8List data = await fileByte.readAsBytes();
List<int> list = data.cast();
request.files
.add(http.MultipartFile.fromBytes('text', list, filename: 'tarea1'));
request.headers.addAll(headers);
request.fields['title'] = title;
request.fields['limitDate'] = limitDate;
request.fields['subjectid'] = subjectid.toString();
request.fields['teacherid'] = teacherid.toString();
request.fields['ext'] = '.txt';
var res = await request.send();
return res.stream.bytesToString().asStream().listen((event) {
var parsedJson = json.decode(event);
print(parsedJson);
});
}
}
And I am getting Expected a value of type 'File', but got one of type 'FilePickerResult'
I do not know how to fix this to send the file... Any ideas on how to go through this?
What you are doing wrong is You are setting FilePickerResult instead of File. [Edited using a different approach for the web.
ElevatedButton(
onPressed: () async {
final result =
await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['txt', 'docx'],
withReadStream:
true,
);
//Edited Part
var file = result!.files.single;
value.setFile(file);
},
child: Text('Seleccionar archivo'))
and also
PlatformFile file = null;
Future setFile(PlatformFile txt) async {
this.file = txt;
this.notifyListeners();
}
Future makePostRequest(
String title, int subjectid, int teacherid, String limitDate) async {
var url = Uri.parse('http://localhost:8000/newHomework');
var request = http.MultipartRequest('POST', url);
var headers = {'Content-Type': 'text/plain; charset=UTF-8'};
request.files.add(new http.MultipartFile(
"text", file.readStream, file.size,
filename: "tarea1"));
request.headers.addAll(headers);
request.fields['title'] = title;
request.fields['limitDate'] = limitDate;
request.fields['subjectid'] = subjectid.toString();
request.fields['teacherid'] = teacherid.toString();
request.fields['ext'] = '.txt';
var res = await request.send();
return res.stream.bytesToString().asStream().listen((event) {
var parsedJson = json.decode(event);
print(parsedJson);
});
}