HTTP Request for Ruby on Flutter Not Working - ruby

The Api request is working on Postman without any issues but with Flutter it is not getting a match
This is my request method that I'm currently using to get the response
static Future getRequest(
{required String baseUrl,
required String path,
required Map<String, String> headers,
required Map<String, String> params,
bool? parsed}) async {
http.Response response;
response = await http.get(
Uri.parse(Uri.http(baseUrl, path, params).toString()),
headers: headers);
print(baseUrl);
print(path);
print(headers.toString());
print(response.body.toString());
if (response.statusCode == HttpStatus.ok) {
return {
"header": {"success": true},
"response": (parsed == null || parsed == true)
? json.decode(response.body)
: response.body
};
} else {
return {
"header": {"success": false},
"httpCode": response.statusCode
};
}
}
How to send a http request to Ruby from flutter?

Related

Why does flutter app always crash after debugging

this is the main.dart file if there is anyone can help me. after crashing it stuck on this message :
Launching lib\\main.dart on sdk gphone x86 arm in debug mode...
lib\\main.dart:1
√ Built build\\app\\outputs\\flutter-apk\\app-debug.apk.
like this
import 'package:dio/dio.dart';
class BaseUrl {
static String url = 'https://awad.mohatim.tech/public/api';
static String real = 'https://awad.mohatim.tech/api/';
static String local = 'http://127.0.0.1:8000/api/';
}
Map<String, String> headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
};
class DioHelper {
static final BaseOptions _options = BaseOptions(
baseUrl: BaseUrl.real,
headers: headers,
validateStatus: (status) {
return status! < 500;
},
);
static final Dio _dio = Dio(_options);
// get login # data = email and password
static Future getLogin({required Map<String, dynamic> data}) async {
try {
Response response = await _dio.post('login', data: data);
return response;
} on DioError catch (e) {
print(e.message);
}
}
// data = name email phone paswword
static Future register({required Map<String, dynamic> data}) async {
try {
Response response = await _dio.post('register', data: data);
return response;
} on DioError catch (e) {
print(e.message);
}
}
// public request
static Future post({required String endpoint, required dynamic data}) async {
Map<String, String> headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
};
try {
Response response = await _dio.post(endpoint, data: data, options: Options(headers: headers));
return response;
} on DioError catch (e) {
print(e.message);
}
}
// public request
static Future get({required String endpoint}) async {
try {
Response response = await _dio.get(endpoint);
return response;
} on DioError catch (e) {
print(e.message);
}
}
static Future getWithToken({required String endpoint, required String token}) async {
Map<String, String> headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
};
try {
Response response = await _dio.get(endpoint, options: Options(headers: headers));
return response;
} on DioError catch (e) {
print(e.message);
}
}
static Future postWithToken({required String endpoint, required dynamic data, required String token}) async {
Map<String, String> headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
};
try {
Response response = await _dio.post(endpoint, data: data, options: Options(headers: headers));
return response;
} on DioError catch (e) {
print(e.message);
}
}
static Future postImage({required String endpoint, required FormData data, required String token}) async {
Map<String, String> headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
};
try {
Response response = await _dio.post(endpoint, data: data, options: Options(headers: headers));
return response;
} on DioError catch (e) {
print(e.message);
}
}
}
I'm trying to connect the app with Laravel admin panel throw API

I'm getting "Unauthenticated" message with a valid token in Laravel Passport using Flutter

I built a Web Service using Laravel Passport for authentication, when I register a user, it generates an access token successfully, but when I am trying to retrieve the user info, I get unauthenticated.
The interesting part is that making the social sign up with Postman, the access token generated works, but when I make the sign up with the app, the access token is not valid.
This is my request code on my mobile app:
Future<Map> socialSignIn(UserSocialAuth userSocialAuth) async {
final String _socialPath = '/social_auth';
Future<Map> socialSignInResponse;
try {
socialSignInResponse = postRequest(_socialPath, userSocialAuth.toJson());
} catch (error, stackTrace) {
print("Exception ocurred: $error stackTrace: $stackTrace");
socialSignInResponse = jsonDecode('{"exception": $error, "stackTrace": $stackTrace}');
}
return socialSignInResponse;
}
/// POST Request
Future<Map> postRequest(String serviceName, Map data) async {
Map responseData = {};
FormData formData = FormData.fromMap(data);
_dio.options.connectTimeout = connectTimeout;
_dio.options.receiveTimeout = receiveTimeout;
try {
Response response = await _dio.post(
_endpoint + '$serviceName',
data: formData,
options: Options(
headers: {
'Authorization': await getAccessToken(),
'Accept': 'application/json'
}
)
);
if (response.statusCode == 200) {
responseData = response.data;
}
} catch (e) {
// An error was received
responseData = {
'error': 'No se pudo conectar con el servidor de $_appName',
'exception': e.toString()
};
}
return responseData;
}
And this is the request for the user data using access token:
Future<Map> currentUser(String accessToken) async {
final String _currentUserPath = '/user';
Future<Map> userDataResponse;
try {
userDataResponse = getRequest(_currentUserPath);
} catch (error, stackTrace) {
print("Exception ocurred: $error stackTrace: $stackTrace");
userDataResponse = jsonDecode('{"exception": $error, "stackTrace": $stackTrace}');
}
return userDataResponse;
}
/// GET Request
Future<Map> getRequest(String serviceName) async {
Map responseData = {};
_dio.options.connectTimeout = connectTimeout;
_dio.options.receiveTimeout = receiveTimeout;
try {
Response response = await _dio.get(
_endpoint + '$serviceName',
options: Options(
headers: {
'Authorization': await getAccessToken(),
'Accept': 'application/json'
}
));
if (response.statusCode == 200) {
responseData = response.data;
}
} catch (e) {
// An error was received
responseData = {
'error': 'No se pudo conectar con el servidor de $_appName',
'exception': e.toString()
};
}
return responseData;
}
I do not know why works with postman and not with the app.
I save the access token with SharedPreferences like this:
/// ----------------------------------------------------------
/// Method that returns the token from Shared Preferences
/// ----------------------------------------------------------
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
Future<String> getAccessToken() async {
final SharedPreferences prefs = await _prefs;
String _authorizationToken;
if (prefs.getString(_accessTokenKey) != null) {
_authorizationToken = 'Bearer ' + prefs.getString(_accessTokenKey);
}
return _authorizationToken;
}
/// ----------------------------------------------------------
/// Method that saves the token in Shared Preferences
/// ----------------------------------------------------------
Future<bool> setAccessToken(String token) async {
final SharedPreferences prefs = await _prefs;
return prefs.setString(_accessTokenKey, token);
}

POST REQUEST _CastError (type '_File' is not a subtype of type 'String' in type cast)

I've been struggling for days trying to make this thing work.
This POST method is to upload an image which should be a "File" and a caption.
The API requires:
PAYLOAD:
- caption
- image
HEADER
- AUTHENTICATION
I'm new to flutter and I've followed a lot of tutorials but nothing seems to work.
here's my code:
static Future<void> addPost(
BuildContext context, String caption, File image) async {
debugPrint("$image");
String imageFile = image.path.split("/").last;
debugPrint("$imageFile");
Utils().showRegisterProgressDialog(context);
final userData = {
"caption": caption,
"image" : image
};
final response = await http.post(
APIServices.HTTP_DOMAIN + APIServices.POST_ADD_NEW,
body: userData,
headers: {"Authentication": "Bearer " + Constants.token});
debugPrint("STATUS: ${response.statusCode}");
if (response.statusCode == 200) {
Utils().hidePostingDialog(context);
Utils().postSuccessDialog(context);
} else {
Utils().hidePostingDialog(context);
Utils().postErrorDialog(context);
}
print(response.body);
return response;
}
I'd appreciate any help and suggestions.
EDIT
I've also tried using MultipartRequest but it returns a statuscode of 500
here's my code:
static Future<void> addPost(
BuildContext context, String caption, File image) async {
Map<String, String> headers = {
"Authentication": "Bearer ${Constants.token}"
};
debugPrint("TOKEN : $headers");
Utils().showPostingDialog(context);
var stream = new http.ByteStream(DelegatingStream.typed(image.openRead()));
var length = await image.length();
var url =
Uri.parse("${APIServices.HTTP_DOMAIN}${APIServices.POST_ADD_NEW}");
debugPrint("TOKEN : $stream");
debugPrint("TOKEN : $length");
debugPrint("TOKEN : $url");
final request = http.MultipartRequest("POST", url);
debugPrint("TOKEN : $request");
debugPrint("TOKEN : $image");
debugPrint("TOKEN : ${image.path}");
var multipartFile =
new http.MultipartFile('file', stream, length, filename: image.path);
debugPrint("TOKEN : ${multipartFile.contentType}");
request.fields['caption'] = caption;
request.headers.addAll(headers);
request.files.add(multipartFile);
var response = await request.send();
debugPrint("TOKEN : ${response.request}");
print(response.statusCode);
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}
Http error 500 is generally seen during a bad request.
I would recommend you to try the exact same request using Postman and see what the result is, you can also try and print the response.message which sometimes can tell you what you did wrong while formatting the request.
Some more advice: try using the DIO package, it is much simpler to format request in it, you can set the header once, also errors are properly formatted, and a bunch of more advanced features are available which are quite helpful.

How return a empty JSON in Spring MVC?

I'm using ajax with GET method, I'm waiting receive a JSON but sometime the response is null and get the error:
SyntaxError: Unexpected end of JSON input
ajax:
$(document).ready(function() {
$("#form_data").submit(function(e) {
e.preventDefault()
var expediente = $('#expediente').val();
$.ajax({
url : 'buscarPaciente' + '?expediente=' + expediente,
dataType : "json",
type : "GET",
contentType : 'application/json',
mimeType : 'application/json',
success : function(data) {
console.log(data.nombre);
},
error : function(xhr, status, error) {
console.log(error)
}
});
})
});
in the controller:
#RequestMapping(value="/buscarPaciente", method = RequestMethod.GET)
public #ResponseBody MntPaciente
buscarPaciente(#RequestParam("expediente") String expediente) {
MntPaciente mntPaciente = servicePx.findByexpediente(expediente);
if (mntPaciente!= null) {
return mntPaciente;
}
return null; // Should I return an empty json? how?
}
There are several ways to do it. The first is to configure the JSON library that used to serialise JSON .In case of Jackson , you can use #JsonInclude to exclude all the empty properties not to serialise and just return an empty MntPaciente :
#JsonInclude(Include.NON_EMPTY)
public class MntPaciente {
}
public #ResponseBody MntPaciente buscarPaciente(#RequestParam("expediente") String expediente) {
....
return new MntPaciente();
}
To apply globally rather to configure for each object , you could use
ObjectMapper om = new ObjectMapper();
om.setSerializationInclusion(Include.NON_EMPTY);
The other way is to change the controller method to return ResponseEntity and directly return a empty JSON string :
public #ResponseBody ResponseEntity buscarPaciente(#RequestParam("expediente") String expediente) {
if (mntPaciente!= null) {
return ResponseEntity.of(mntPaciente);
}else{
return ResponseEntity.of("{}");
}
}

Returning zip file from REST to client not popping up the file

I am trying to downloada zip file sent from a REST by adding the Content-Type and the Content-Disposition doing the following:
Server-side
#Produces("application/x-zip-compressed")
public Response export(#PathParam("username") String username,
#Context UriInfo ui) {
long timeStamp = new Date().getTime();
String exportedFolder = "/home/madmin/pods/"+username+"/download/";
String Path = ui.getRequestUri().toString()
.replace(replaceMe + username, "");
Path = Path.replace("http://", "https://");
Path = Path.replace(",system/export", "");
String outputZipFile = exportedFolder+"exported_on_"+timeStamp+".zip";
String sourceFolder = null;
File file = new File(exportedFolder);
if (!file.exists()) {
if (file.mkdirs()) {
System.out.println("Directory is created!");
} else {
System.out.println("Failed to create directory for exporting!");
//return ;
}
}
constructGraphs cGraphs = new constructGraphs(Path, username);
sourceFolder = cGraphs.writeGraphFiles();
generateZipFile appZip = new generateZipFile(sourceFolder,outputZipFile);
appZip.generateFileList(new File(sourceFolder));
appZip.zipIt(outputZipFile);
//Read the outputZipFile as inputStream and return it
FileInputStream fileIs = null;
try {
fileIs = new FileInputStream(outputZipFile);
} catch (IOException e) {
throw new WebApplicationException(404);
}
String fileName= outputZipFile.substring(outputZipFile.lastIndexOf("/")+1, outputZipFile.length());
return Response.status(Status.OK).entity(fileIs).header("Content-Disposition","attachment; filename = "+fileName).build();
}
Client-side:
The client side on the other hand is expecting application/x-zip-compressed as follows:
$http({
method: 'GET',
url: uri,
headers: {
'Accept': 'application/x-zip-compressed'
},
withCredentials: true
}).
success(function(data, status, headers) {
if (status == 200 || status == 201) {
notify('Success', 'Node exported.');
}
}).
error(function(data, status) {
if (status == 401) {
notify('Forbidden', 'Authentication required to edit the resource.');
} else if (status == 403) {
notify('Forbidden', 'You are not allowed to edit the resource.');
} else {
notify('Failed', status + " " + data);
}
});
The file is not popping up, instead I see the input stream in the response.
Is there anything wrong I am doing here? Any help would be really appreciated.
It is not possible with AJAX and I assume you are using angularjs http serivce in this case. See: Why threre is no way to download file using ajax request?.
You have different options to solve your problem.
For instance: easiest way to open a download window without navigating away from the page
or How do you serve a file for download with AngularJS or Javascript?

Resources