I'm writing a Node.js server and I'm trying to fetch data from an API and return it to my user. I'm taking the insightlyResponse and trying to convert to JSON. Here's my code:
insightlyResponse.setEncoding('utf8');
let rawData = '';
insightlyResponse.on('data', (chunk) => rawData += chunk);
insightlyResponse.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
responseData = "PARSED";
} catch (e) {
responseData = `Got error: ${e.message}`
}
response.end(responseData);
});
The error is Got error: Unexpected token \u001f in JSON at position 0. What does this mean and what am I doing wrong?
Figured it out! I double-checked the API and realized that it can return compressed responses. Turned off that setting and works like a charm!
Related
I was working on a flutter package that I made https://github.com/pratikbaid3/flutter_client_sse. This is used to consume server-sent events. This works fine when the response returned is comparatively small. But as soon as the response grows large, I start getting this error flutter: FormatException: Unterminated string
This is the code snippet used to get the sse
while (true) {
try {
_client = http.Client();
var request = new http.Request("GET", Uri.parse(url));
request.headers["Cache-Control"] = "no-cache";
request.headers["Accept"] = "text/event-stream";
request.headers["Cookie"] = token;
Future<http.StreamedResponse> response = _client.send(request);
await for (final data in response.asStream()) {
await for (final d in data.stream) {
final rawData = utf8.decode(d);
final event = rawData.split("\n")[1];
if (event != null && event != '') {
yield SSEModel.fromData(rawData);
}
}
}
} catch (e) {
print('---ERROR---');
print(e);
yield SSEModel(data: '', id: '', event: '');
}
await Future.delayed(Duration(seconds: 1), () {});
}
My guess is that a part of the response is lost due to the large size.
So after hours of debugging, I found that in my current approach when the response is very large, part of it is truncated (Not sure why). I changed the code to read one line at a time and got it to work.
data.stream
..transform(Utf8Decoder())
.transform(LineSplitter())
.listen((dataLine) {
//Do what you want with the data here
}
This seemed to solve the issue.
The complete code can be found at https://github.com/pratikbaid3/flutter_client_sse
In my project I get my json string which later on i tried to assign to it a jsonResponse variable but I got an error like : The argument type 'Response' can't be assigned to the parameter type 'String'.
Here's my code:
Future getMahalle() async {
BaseOptions options = new BaseOptions(
baseUrl: globals.PROD_URL,
connectTimeout: 5000,
receiveTimeout: 3000,
);
Dio dio = new Dio(options);
dio.options.headers["Authorization"] = "Bearer ${globals.USER_TOKEN}";
try {
var response =
await dio.get(globals.SELECT_URL); //'api/hizlirapor/selects'
final jsonResponse = jsonDecode(response); //Here is the error line
MahalleModel mahalleList =
MahalleModel.fromJson(jsonDecode(response.data['mahalle']));
return mahalleList;
} on DioError catch (e) {
debugPrint("ERRORR!!!!!!!!!!!!! ${e.error.toString()}");
return null;
}
}
I'm trying to implement this article for example and got stuck. Thanks for help!
You don't have to decode json returned since you are using dio, dio does that for you.
// if it's a single value than try this.
MahalleModel mahalleList = response.data.map<MahalleModel>((mahalle) => MahalleModel.fromJson(mahalle));
// if it's a list than try this.
List<MahalleModel> mahalleList = response.data['mahalle'].map<MahalleModel>((mahalle) => MahalleModel.fromJson(mahalle)).toList();
I have created a url scraper function, working and tested on Google Cloud, but I am really drawing a blank on how to invoke it. I have tried two methods, one using the cloud_functions package, and the other using a standard HTTPS get. I've tried looking online, but none of the solutions/guides involve functions with an input from the Flutter app, and an output back to the app.
Here's the structure of the function (which is working alright). I've named this function Parse in Google Cloud Platform.
<PYTHON PACKAGE IMPORTS>
def Parser(url):
<URL PARSE FUNCTIONS>
return source, datetime, imageurl, keyword
def invoke_parse(request):
request_json = request.get_json(silent=True)
file = Parser(request_json['url'])
return jsonify({
"source": file[0],
"datetime": file[1],
"imageurl": file[2],
"keyword": file[3],
})
The first method I tried was using an HTTP CALL to get the function. But that isn't working, even though there are no errors - I suspect it's just returning nothing.
parser(String url) async{ // Here I honestly don't know where to use the url input within the function
var uri = Uri.parse(<Function URL String>);
HttpClient client;
try {
var request = await client.getUrl(uri);
var response = await request.close();
if (response.statusCode == HttpStatus.ok) {
var json = await response.transform(utf8.decoder).join();
Map data = jsonDecode(json) as Map;
source = data['source']; // These are the variables used in the main Flutter app
postedAt = data['datetime'];
_imageUrl = data['image'];
keyword = data['keyword'];
} else {
print('Error running parse:\nHttp status ${response.statusCode}');
}
} catch (exception) {
print('Failed invoking the parse function.');
}
}
That didn't work, so I thought I might alternatively use the cloud_functions package as follows (in lieu of the previous):
parser(String url) async {
var functionUrl = <FUNCTION URL>;
HttpsCallable callable = CloudFunctions.instance.getHttpsCallable(functionName: 'Parse')
..timeout = const Duration(seconds: 30);
try {
final HttpsCallableResult result = await callable.call(
<String, dynamic>{
'url': url,
}
);
setState(() {
source = result.data['source']; //THESE ARE VARIABLES USED IN THE FLUTTER APP
postedAt = result.data['datetime'];
_imageUrl = result.data['image'];
keyword = result.data['keyword'];
});
}
on CloudFunctionsException catch (e) {
print('caught firebase functions exception');
print(e.code);
print(e.message);
print(e.details);
} catch (e) {
print('caught generic exception');
print(e);
}
}
In the latter case, the code ran without errors but doesn't work. My flutter log states the following error:
I/flutter ( 2821): caught generic exception
I/flutter ( 2821): PlatformException(functionsError, Cloud function failed with exception., {code: NOT_FOUND, details: null, message: NOT_FOUND})
which I'm assuming is also an error at not being able to read the function.
Any help on how I should go about processing my function would be appreciated. Apologies if something is a really obvious solution, but I am not familiar as much with HTTP requests and cloud platforms.
Thanks and cheers.
Node Js Backend Function
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.test = functions.https.onCall(async (data, context) => {
functions.logger.info("Hello logs: ", {structuredData: true});
functions.logger.info( data.token, {structuredData: true});
}
Flutter frontend
1- pubspec.yaml
cloud_functions: ^1.1.2
2 - Code
HttpsCallable callable = FirebaseFunctions.instance.httpsCallable('test');
final HttpsCallableResult results = await callable.call<Map>( {
'token': token,
});
I did not able to store json response from API in sqflite database but i already parsed json response in list and also i stored similar data in sqflite database.
To stored locally i got success and able to perform CRUD operation and sending it to server, similarly i also able to perform CRUD operation on API data but problem arises on synchronization between local and json data.
the below code id for calling json data
Future<List<Activities>> getData() async {
List<Activities> list;
var res = await http
.post("http://xxxx/get-activity", headers: {
HttpHeaders.authorizationHeader: "Bearer " + _token.toString()
});
if (res.statusCode == 200) {
var data = json.decode(res.body);
var rest = data["data"] as List;
// print(rest);
list = rest.map<Activities>((json) => Activities.fromJson(json)).toList();
// print('okay, ${rest[0]}!');
} else {
print('something error');
}
print("List Size: ${list.length}");
return list;
}
solved
var data = json.decode(res.body);
var activities= data["data"] as List;
for (var activity in activities) {
Activity actData = Activity.fromMap(activity);
batch.insert(actTable, actData.toMap());
}
Solution! Please use this flutter plugin json_store
I'm trying to make a ReactJS app that utilizes the Spotify API, but I keep receiving this error:
const client_id = ''; //hidden
const redirect_uri = 'http://localhost:3000/'
let accessToken;
const Spotify = {
async getAccessToken(){
if (accessToken){
return accessToken;
}
try{
let response = await fetch(`https://cors-anywhere.herokuapp.com/https://accounts.spotify.com/authorize?client_id=${client_id}&response_type=token&redirect_uri=${redirect_uri}`);
if (response.ok){
let jsonResponse = await response.json();
console.log(jsonResponse);
}
}catch (e){
console.log(e);
}
}
}
export default Spotify;
I've read around and I hear this is a server-side issue? If so, is there a work-around it? By the way I am using this https://cors-anywhere.herokuapp.com/ to prevent the CORS error.
Thanks for any help. I'll keep working on it. If I find anything, I'll post up the solution right away!