flutter - Unable to parse JSON message: The document is empty - android

I am working on a cart system. I am trying to sum of the product price added into the list. When I update the product quantity it gives me following error.
I am using getx for this. But I don't think it is a getx error.
Unable to parse JSON message: The document is empty.
countTotalPrice() async {
totalPrice = 0.0;
for (var i = 0; i < cartProducts.length; i++) {
totalPrice += cartProducts[i]['total'] as double;
}
update();
}
addToCart(int index) async {
Map data = {
"product_name": productsList[index]['english_name'],
"price": productsList[index]['sale_price'],
"qty": 1,
"total": productsList[index]['sale_price'],
};
cartProducts.add(data);
countTotalPrice();
update();
}
updateQuantity(index, count) {
Map data = cartProducts[index];
data['qty'] = count;
data['total'] = double.parse(data['price']) * data['qty'];
countTotalPrice();
update();
}

try this
data['total'] = double.parse(data['price'].toString()) * double.parse(data['qty'].toString())).toString();

Related

Creating a new map using key value pairs, not saving

Im decoding a json and transforming it in a variable of type map [string , List < LatLng>] and trying to retun it as the code of this function, howevwer im unable to save it as a map in the variable _polyFinal:
static getPoligoni() async {
http.Response _response = await http.get('$api/posizione/poligoni',
headers: {'Authorization': '${dataController.tokenBearer.value}'});
if (_response.statusCode == 200) {
Map<String, dynamic> _json = jsonDecode(_response.body);
var _poly = Map.from(_json["Poligoni"]).map(
(k, v) {
return MapEntry<String, List<String>>(
k,
List<String>.from(
v.map((x) => x),
),
);
},
);
List<String> _verticiRaw;
List<LatLng> _vertici = [];
Map<String, List<LatLng>> _polyFinal = {};
for (String key in _poly.keys) {
// print(_verticiRaw);
_verticiRaw?.clear();
_verticiRaw = _poly[key];
for (int i = 0; i < _verticiRaw.length; i++) {
print(i);
var _posVirgola = _verticiRaw[i].indexOf(',');
String posx, posy;
posx = _verticiRaw[i].substring(0, _posVirgola);
posy = _verticiRaw[i].substring(_posVirgola + 1);
var lat = double.tryParse(posx);
var lon = double.tryParse(posy);
_vertici.add(LatLng(lat, lon));
}
print(key);
print(_vertici);
_polyFinal.putIfAbsent(key, () => _vertici);
_vertici?.clear();
}
dataController.showLoadingStatus(false);
// print(_polyFinal);
// return _polyFinal;
If I try to print the polyFinal variable at the end of the cycle i get an empty map, And if I print the variable during the cycle every key-value pair get transformed in the following
key --> last vertici value
I tried to chek the values of both key and vertici and they are different every time the cycle is run.
Any help understanding this behavior is greatly appreciated,
Best Regards.
Resolved by putting
_polyFinal.putIfAbsent(key, () => _vertici.toList());
Maybe _vertici is just a pointer and not the value itself.

Insert array items on conditions and calculate its sum

"PaymentMode": "Cash",
"Amount": 1000,
"PaymentReferenceNumber": "",
},
{
"PaymentMode": "CcAve",
"Amount": 500,
"PaymentReferenceNumber": "",
},
{
"PaymentMode": "cash",
"Amount": 0,
"PaymentReferenceNumber": "IN0001-113",
},
{
"PaymentMode": "Credited",
"Amount": 500,
"PaymentReferenceNumber": "IN0001-114",
}
This is how i get my json response. What i need to do is that, those 'amount' value whose corresponding payment reference number is empty or null needs to be added.This is what i have done
public int getTotalPayments() {
int total = 0;
for(OrderPayment payment : orderPayments) {
if(payment.getPaymentReferencenumber().isEmpty()||payment.getPaymentReferencenumber().equals("NULL")){
total += payment.getAmount();
}
}
return total;
}
But I am getting wrong. Can anyone help
Look at your logic, you say you're getting the sum of:
References that are empty
OR
References that are NOT "NULL"
And most of the stuff is not null.
To answer your question, just remove the !:
if(payment.getPaymentReferencenumber().isEmpty()||payment.getPaymentReferencenumber().equals("NULL")){
Which is
- References that are empty
OR
- References that are "NULL"
Your Condition is wrong . In am assuming you are checking for a blank Reffrence number here.
So it should be as :-
public int getTotalPayments() {
int total = 0;
for(OrderPayment payment : orderPayments) {
if (isEmpty(payment.getPaymentReferencenumber())) {
total += payment.getAmount();
}
}
return total;
}
private boolean isEmpty(String str) {
if (TextUtils.isEmpty(str))
return true;
return str.toLowerCase().equals("null");
}

how to parse a JSON data in side a table layout dynamically?In Android from a URL

I am Parsing a a JSON data from a URL..
I followed this tutorial to parse the dynamic JSON data
now am parsing the data,.
in a List view.. when I click on that list view a New Item view will appear in that I want to add some contents which are form a JSON data.. But its viewing the last one of the data So I parse it with a string format but I am getting the data in string but I want that data in a table..
this is my JSON data{
"request": "ok",
"query": {
"result": [
{
"details": [
{
"offers": [
{
"id": "UUkY8",
"model": "XL"
},
{
"id": "UUkY8",
"model": "XXL"
}
],
"count": 2,
"url": "http://www.wallmart.com"
},
{
"offers": [
{
"id": "NNkz4",
"model": "XL"
},
{
"id": "NNkz4",
"model": "XXL"
}
],
"count": 2,
"url": "http://www.amazon.com"
}
],
"flag": [
"http://www.donkersct.nl/wordpress/wp-content/uploads/2012/07/stackoverflow.png"
]
}
]
}
}
and I am parsing that in this way
JSONArray json_results_details =c.getJSONArray("details");
System.out.println("looping json_results_details");
String strOffermodel="";
for (int j = 0; j < c.length(); j++) {
System.out.println("looping json_results_details[" + j +"]" + "json_results_details.length() -->" + json_results_details.length());
if (j < json_results_details.length()) {
JSONObject d = json_results_details.getJSONObject(j);
stridsName += d.optString("name")+",";
stridsURLs += d.optString("url")+",";
// Get site details
long lOffer_Counts =-1;
try {
lOffer_Counts= Long.parseLong(d.optString("offers_count"));
} catch(Exception e) {
lOffer_Counts =-1;
}
strOffersCount+= String.valueOf(lOffer_Counts) + ",";
if(lOffer_Counts > 0) {
JSONArray json_offers = d.getJSONArray("offers");
System.out.println(json_offers.toString());
String strmodel="";
for (int k = 0; k < json_offers.length(); k++) {
JSONObject e = json_offers.getJSONObject(k);
map.put("id", e.optString("id"));
map.put("model", e.optString("model"));
strmodel += e.optString("model") + "$";
}
strOffermodel += strmodel + ",";
}
else
{
strOffermodel += ",";
}
map.put("id", stridsName);
map.put("model", strOffermodel);
}
}
arraylist.add(map);
So no I am getting the Model in loop.
as Model:XL,XXL/XL,XXL...
I tried with list view but failed now I am trying with table View..
But I want the output should be as
Here Only one id is showing I want all ID and all Model as a comperation..
Please help me to find out I am using a table inside a listviw, I tried with Listview inside a Listview.. But not worked..
I tried with increment the data means ID/Model with for loop as i+1 But its incrementing the value
means I am expected as
map.put("id", strOfferid);
map.put("id1", strOfferid1);
map.put("id2", strOfferid2);
map.put("id3", strOfferid3);
But I am incrementing the value like
Model:XL1,XXL1/XL2,XXL2/XL3,XXL3
So any one please help Regarding this..
use instead of
JSONObject d = json_results_details.getJSONObject(j);
this
JSONObject d = new JSONbject(json_results_details.getJSONObject(j));

How to retrieve more than 1000 rows from Parse.com?

I have been using Parse to retrieve a data for a list view. Unfortunately they limit requests to 100 by default to a 1000 max. I have well over that 1000 max in my class. I found a link on the web which shows a way to do it on iOS but how would you do it on Android? Web Link
I am currently adding all the data into a arraylist in a loop until all items are complete (100) then adding them to the list
I have figured out how to achieve my goal:
Declare Global Variable
private static List<ParseObject>allObjects = new ArrayList<ParseObject>();
Create Query
final ParseQuery parseQuery = new ParseQuery("Objects");
parseQuery.setLimit(1000);
parseQuery.findInBackground(getAllObjects());
Callback for Query
int skip=0;
FindCallback getAllObjects(){
return new FindCallback(){
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
allObjects.addAll(objects);
int limit =1000;
if (objects.size() == limit){
skip = skip + limit;
ParseQuery query = new ParseQuery("Objects");
query.setSkip(skip);
query.setLimit(limit);
query.findInBackground(getAllObjects());
}
//We have a full PokeDex
else {
//USE FULL DATA AS INTENDED
}
}
};
}
Here is a JavaScript version without promises..
These are the global variables (collections are not required, just a bad habit of mine)..
///create a collection of cool things and instantiate it (globally)
var CoolCollection = Parse.Collection.extend({
model: CoolThing
}), coolCollection = new CoolCollection();
This is the "looping" function that gets your results..
//recursive call, initial loopCount is 0 (we haven't looped yet)
function getAllRecords(loopCount){
///set your record limit
var limit = 1000;
///create your eggstra-special query
new Parse.Query(CoolThings)
.limit(limit)
.skip(limit * loopCount) //<-important
.find({
success: function (results) {
if(results.length > 0){
//we do stuff in here like "add items to a collection of cool things"
for(var j=0; j < results.length; j++){
coolCollection.add(results[j]);
}
loopCount++; //<--increment our loop because we are not done
getAllRecords(loopCount); //<--recurse
}
else
{
//our query has run out of steam, this else{} will be called one time only
coolCollection.each(function(coolThing){
//do something awesome with each of your cool things
});
}
},
error: function (error) {
//badness with the find
}
});
}
This is how you call it (or you could do it other ways):
getAllRecords(0);
IMPORTANT None of the answers here are useful if you are using open
source parse server then it does limit 100 rows by default but you can
put any value in query,limit(100000) //WORKS
No need for recursive
calls just put the limit to number of rows you want.
https://github.com/parse-community/parse-server/issues/5383
JAVA
So after 5 years, 4 months the above answer of #SquiresSquire needed some changes to make it work for me, and I would like to share it with you.
private static List<ParseObject>allObjects = new ArrayList<ParseObject>();
ParseQuery<ParseObject> parseQuery = new ParseQuery<ParseObject>("CLASSNAME");
parseQuery.setLimit(1000);
parseQuery.findInBackground(getAllObjects());
FindCallback <ParseObject> getAllObjects() {
return new FindCallback <ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
allObjects.addAll(objects);
int limit = 1000;
if (objects.size() == limit) {
skip = skip + limit;
ParseQuery query = new ParseQuery("CLASSNAME");
query.setSkip(skip);
query.setLimit(limit);
query.findInBackground(getAllObjects());
}
//We have a full PokeDex
else {
//USE FULL DATA AS INTENDED
}
}
}
};
In C# I use this recursion:
private static async Task GetAll(int count = 0, int limit = 1000)
{
if (count * limit != list.Count) return;
var res = await ParseObject.GetQuery("Row").Limit(limit).Skip(list.Count).FindAsync();
res.ToList().ForEach(x => list.Add(x));
await GetAll(++count);
}
JS version:
function getAll(list) {
new Parse.Query(Row).limit(1000).skip(list.length).find().then(function (result) {
list = list.concat(result);
if (result.length != 1000) {
//do here something with the list...
return;
}
getAll(list);
});
}
Usage: GetAll() in C#, and getAll([]) in JS.
I store all rows from the class Rowin the list. In each request I get 1000 rows and skip the current size of the list. Recursion stops when the current number of exported rows is different from the expected.
**EDIT : Below answer is redundant because open source parse server doesn't put any limit on max rows to be fetched
//instead of var result = await query.find();
query.limit(99999999999);//Any value greater then max rows you want
var result = await query.find();**
Original answer:
Javascript / Cloud Code
Here's a clean way working for all queries
async function fetchAllIgnoringLimit(query,result) {
const limit = 1000;
query.limit(limit);
query.skip(result.length);
const results = await query.find();
result = result.concat(results)
if(results.length === limit) {
return await fetchAllIgnoringLimit(query,result );
} else {
return result;
}
}
And here's how to use it
var GameScore = Parse.Object.extend("GameScore");
var query = new Parse.Query(GameScore);
//instead of var result = await query.find();
var result = await fetchAllIgnoringLimit(query,new Array());
console.log("got "+result.length+" rows")
YAS (Yet Another Solution!) Using async() and await() in javascript.
async parseFetchAll(collected = []) {
let query = new Parse.Query(GameScore);
const limit = 1000;
query.limit(limit);
query.skip(collected.length);
const results = await query.find();
if(results.length === limit) {
return await parseFetchAll([ ...collected, ...results ]);
} else {
return collected.concat(results);
}
}
A Swift 3 Example:
var users = [String] ()
var payments = [String] ()
///set your record limit
let limit = 29
//recursive call, initial loopCount is 0 (we haven't looped yet)
func loadAllPaymentDetails(_ loopCount: Int){
///create your NEW eggstra-special query
let paymentsQuery = Payments.query()
paymentsQuery?.limit = limit
paymentsQuery?.skip = limit*loopCount
paymentsQuery?.findObjectsInBackground(block: { (objects, error) in
if let objects = objects {
//print(#file.getClass()," ",#function," loopcount: ",loopCount," #ReturnedObjects: ", objects.count)
if objects.count > 0 {
//print(#function, " no. of objects :", objects.count)
for paymentsObject in objects {
let user = paymentsObject[Utils.name] as! String
let amount = paymentsObject[Utils.amount] as! String
self.users.append(user)
self.payments.append(amount)
}
//recurse our loop with increment because we are not done
self.loadAllPaymentDetails(loopCount + 1); //<--recurse
}else {
//our query has run out of steam, this else{} will be called one time only
//if the Table had been initially empty, lets inform the user:
if self.users.count == 1 {
Utils.createAlert(self, title: "No Payment has been made yet", message: "Please Encourage Users to make some Payments", buttonTitle: "Ok")
}else {
self.tableView.reloadData()
}
}
}else if error != nil {
print(error!)
}else {
print("Unknown Error")
}
})
}
adapted from #deLux_247's example above.
You could achieve this using CloudCode... Make a custom function you can call that will enumerate the entire collection and build a response from that but a wiser choice would be to paginate your requests, and fetch the records 1000 (or even less) at a time, adding them into your list dynamically as required.
GENERIC VERSION For SWIFT 4:
Warning: this is not tested!
An attempt to adapt nyxee's answer to be usable for any query:
func getAllRecords(for query: PFQuery<PFObject>, then doThis: #escaping (_ objects: [PFObject]?, _ error: Error?)->Void) {
let limit = 1000
var objectArray : [PFObject] = []
query.limit = limit
func recursiveQuery(_ loopCount: Int = 0){
query.skip = limit * loopCount
query.findObjectsInBackground(block: { (objects, error) in
if let objects = objects {
objectArray.append(contentsOf: objects)
if objects.count == limit {
recursiveQuery(loopCount + 1)
} else {
doThis(objectArray, error)
}
} else {
doThis(objects, error)
}
})
}
recursiveQuery()
}
Here's my solution for C# .NET
List<ParseObject> allObjects = new List<ParseObject>();
ParseQuery<ParseObject> query1 = ParseObject.GetQuery("Class");
int totalctr = await query1.CountAsync()
for (int i = 0; i <= totalctr / 1000; i++)
{
ParseQuery<ParseObject> query2 = ParseObject.GetQuery("Class").Skip(i * 1000).Limit(1000);
IEnumerable<ParseObject> ibatch = await query2.FindAsync();
allObjects.AddRange(ibatch);
}

Error parsing JSON data from Facebook using FQL

I am trying to parse a result (JSON) fetched from the Facebook API using FQL in an Android Application.
I have been able to parse all of the result set except this part:
[10151392619250579,10151392618640579,10151392618590579,10151392618785579,10151392618835579,10151392618885579,10151392619010579,10151392619155579]
The FQL query I am making is:
SELECT app_data FROM stream WHERE filter_key in (SELECT filter_key FROM stream_filter WHERE uid = me() AND type = 'newsfeed') AND is_hidden = 0 LIMIT 200
Which returns a result like this:
{
"app_data": {
"attachment_data": "[]",
"images": "[10151392619250579,10151392618640579,10151392618590579,10151392618785579,10151392618835579,10151392618885579,10151392619010579,10151392619155579]",
"photo_ids": [
"10151392619250579",
"10151392618640579",
"10151392618590579",
"10151392618785579",
"10151392618835579",
"10151392618885579",
"10151392619010579",
"10151392619155579"
]
}
}
And this is the code I have used to fetch the data:
// GET THE APP DATA
if (JOFeeds.has("app_data")) {
String strAppData = JOFeeds.getString("app_data");
if (strAppData.equals("[]")) {
// DO NOTHING
} else {
JSONObject JOAppData = new JSONObject(strAppData);
if (JOAppData.has("photo_ids")) {
String strPhotoIDS = JOAppData.getString("photo_ids");
JSONArray JAPhotoIDS = new JSONArray(strPhotoIDS);
Log.e("JAPhotoIDS", JAPhotoIDS.toString());
for (int j = 0; j < JAPhotoIDS.length(); j++) {
JSONObject JOPhotoIDS = JAPhotoIDS.getJSONObject(j);
Log.e("PHOTO IDS", JOPhotoIDS.toString());
}
}
}
}
The logcat however, always shows this error:
12-13 15:54:36.390: W/System.err(5841): org.json.JSONException: Value 10151392619250579 at 0 of type java.lang.Long cannot be converted to JSONObject
Clearly I am wrong in the coding. Can anyone provide any suggestions on what the proper approach / code should be?
the part where you are parsing the photo_ids is wrong, it should be like:
if (JOAppData.has("photo_ids")) {
JSONArray JAPhotoIDS = JOAppData.getJSONArray("photo_ids");
Log.e("JAPhotoIDS", JAPhotoIDS.toString());
for (int j = 0; j < JAPhotoIDS.length(); j++) {
String id = JAPhotoIDS.getString(j);
Log.e("PHOTO IDS", id);
}
}
Your JSONArray JAPhotoIDS includes an array of Long (not JSONObject).
So instead using
JSONObject JOPhotoIDS = JAPhotoIDS.getJSONObject(j);
use
Long lPhotoIDS = JAPhotoIDS.getLong(j);

Categories

Resources