I wasn't sure how to frame the question title, but, here is what i am trying to do.
Using Parse.com
I have a table - Surveys and it has a column with Array datatype. I have a JSONArray stored in this column. The JSONArray has 3 JSONObjects. I have to loop through the 3 JSONObjects, get a field with key "type" and use the value (for example "type_dob") of this key, to query a separate table again. I need this to be done in a row, for example once the result for first key is retrieved, then i have to perform the query for second key.
How can i achieve this?
Sample JSON: Questions: [{"type":"type_dob","id":"I27y16N5gX"},{"type":"type_text","id":"jGAujtNNZc"},{"type":"type_radio","id":"cCDlrrJYKI"}]
My present code:
public void getDataFromServer() {
ParseUser user = ParseUser.getCurrentUser();
if (user != null) {
showProgressDialog("Getting Survey details...");
int survey_count = user.getInt(Const.Parse_User.SURVEY_COUNT);
Log.d(Const.DEBUG, "Survey Count: " + survey_count);
String current_survey = "survey_" + (survey_count + 1);
Log.d(Const.DEBUG, "Current Survey: " + current_survey);
ParseQuery<ParseObject> query = ParseQuery.getQuery("Surveys");
query.whereEqualTo(Const.Parse_SURVEYS.SURVEY_ID, current_survey);
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
dismissProgressDialog();
if (e != null) {
Log.d(Const.DEBUG, "Exception while getting data from Parse - Surveys table");
} else {
if (list.size() > 0) {
ParseObject object = list.get(0);
try {
String questions_array = object.getJSONArray(Const.Parse_SURVEYS.QUESTIONS).toString();
Log.d(Const.DEBUG, "Questions: " + questions_array);
JSONArray array = object.getJSONArray(Const.Parse_SURVEYS.QUESTIONS);
for (int i = 0; i < array.length(); i++) {
JSONObject jsonObject = array.getJSONObject(i);
String type = jsonObject.get("type").toString();
//I should write the query for getting data from table matching the String type. //If i do a findInBackground query for each of the key, then its done in a background thread
//and the for loop exists even before the result for first key comes back.
//How can i handle this?
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
});
}
}
Let me know if you need anything else?
I think you are moving slightly in a unfortunate direction with your db design.
As far as I can tell from you question, the better approach for you would be to store an Array of pointers. For instance, having a data class in Parse.com called 'Question', which stores a type and whatever other properties you need.
Now assume you have an Array instead in your 'Surveys' class. Then your code gets rather simple:
ParseQuery<ParseObject> query = ParseQuery.getQuery("Surveys");
query.whereEqualTo(Const.Parse_SURVEYS.SURVEY_ID, current_survey);
query.include(Const.Parse_SURVEYS.QUESTIONS); // <- IMPORTANT
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
ParseObject object = list.get(0);
// get all Question objects
List<ParseObject> array = object.getList(Const.Parse_SURVEYS.QUESTIONS);
// no need to fetch, the data is here
for (ParseObject question: array) {
String type = question.getString("type");
String question = question.getString("question");
List<String> answerOptions = question.getList("options")
...
}
}
}
If for some reason you cannot transition to this design, then I believe you want to look into Bolts https://github.com/BoltsFramework/Bolts-Android. With this you get the same async abilities as Promises does in javascript. This means that you can que up a range of background jobs and return only when all are completed.
Though Bolts will aid you, it will not avoid exiting your for-loop before it has completed. This is however just a matter of design, meaning that as long as you are aware of the flow of our program, you can design it accordingly. For instance delaying the dismiss of a progress dialog until all background tasks has completed (or failed).
I however suggest that you look into the documentation about the query.include() capabilities together with pointer arrays.
i fetched data like this way from data parse table.
ParseQuery<ParseObject> query = ParseQuery.getQuery("Surveys");
query.whereEqualTo(Const.Parse_SURVEYS.SURVEY_ID, current_survey);
query.include(Const.Parse_SURVEYS.QUESTIONS); // <- IMPORTANT
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> list, ParseException e) {
ParseObject object = list.get(0);
// first initilization Jsonobject Array list.
List<JSONObject> jsobj = new ArrayList<JSONObject>();
jsobj = object.getList(Const.Parse_SURVEYS.QUESTIONS);
// no need to fetch, the data is here
for (int i = 0; i < jsobj.size(); i++) {
Log.e("in the For loop ", ": : ::111111 : " + jsobj.get(i));
JSONObject arr1 = new JSONObject((Map) jsobj.get(i)); // jsobj.get(i);
Log.e("in the For loop ", ": : ::111111 : " + arr1);
try {
Log.e("in the For loop ",
": : ::111111 : " + arr1.getString("name"));
// hear u want to store data in Custom Array list.
// other wise u store in single String value
String type = arr1.getString("type");
String question = arr1.getString("question");
String options = arr1.getString("options");
// this is my custom getter setter class
GetIngredients ai = new GetIngredients();
ai.setName(arr1.getString("type"));
ai.setQty(arr1.getString("question"));
ai.setUnit(arr1.getString("options")) ;
// this is my custom array
arr_Ingredients.add(ai);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.e("in the For loop ", ": : :: : " + jsobj.get(i));
}
}
in my parse data base column type is "Array".
Related
I'm using parse backend to store and retrieve the datas for my android app, the storing gets done properly but i have problem in retrieving it. I just went through the parse documentation to retrieve the result but what i get is just 0 for all the retrieved values..im suret that the class exists in the parse cloud with valid values but still i get 0 for all the queries.. this is my code to save:
Toast.makeText(getApplicationContext(),"writing to parse",Toast.LENGTH_SHORT).show();
ParseObject dataObject = new ParseObject("Score");
dataObject.put("correct",correctAnswers);
dataObject.put("wrong",wrongAnswers);
dataObject.put("percent", percentage);
dataObject.saveInBackground();
this is how i get back the saved data
ParseQuery<Score> query = ParseQuery.getQuery("Score");
try {
List<Score> scoreList = query.find();
} catch (ParseException e) {
e.printStackTrace();
}
query = ParseQuery.getQuery("Score");
final Activity ctx = this;
query.findInBackground( new FindCallback<Score>() {
#Override public void done(List<Score> scoreList, ParseException e) {
if ( e == null ) {
ParseObject dataObject = ParseObject.create("Score");
int p = dataObject.getInt("correct");
int q = dataObject.getInt("wrong");
int r = dataObject.getInt("percent");
Toast.makeText(ExamRecordActivity.this,String.valueOf(p),Toast.LENGTH_SHORT).show();
Toast.makeText(ExamRecordActivity.this,String.valueOf(q),Toast.LENGTH_SHORT).show();
Toast.makeText(ExamRecordActivity.this,String.valueOf(r),Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ctx,
"Error updating questions - please make sure you have internet connection",
Toast.LENGTH_LONG).show();
}
}
});
Inside the done method you are creating a new by calling ParseObject dataObject = ParseObject.create("Score"); and then trying to read values from it without putting any in.
I don't know what the structure of your class is but you need to be iterating through List<Score> scoreList in order to get the queried data.
I'm making a small application. trying to retrieve posts inserted, and then I want to retrieve only new inserted posts, and not retrieving all the posts again.
So do you have any idea on how to I can retrieve last items ( Since the list object retrieved)
Here my Query code :
public void getFeed(int limit, int skip){
ParseQuery<ParseObject> query = ParseQuery.getQuery("Feed");
query.setSkip(skip);
query.setLimit(limit);
query.setCachePolicy(ParseQuery.CachePolicy.CACHE_ELSE_NETWORK);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> feedList, ParseException e) {
if (e == null) {
for (int i = 0; i < feedList.size(); i++) {
Post p = new Post(feedList.get(i).get("Text").toString());
mAdapter.addItem(p);
}
Log.d("result", "Here is it:" + feedList.size());
mRecyclerView.setAdapter(mAdapter);
} else {
Log.d("Feed", "Error: " + e.getMessage());
}
}
});
}
keep the last time you checked and then use that time to pull anything greater than the last time checked from the createdAt column or updatedAt column (if its possible for someone to update something you are pulling) of the object. then after your query is finished update that time to the current time.
you can store the viewed posts count and next time when retrieving the list set the count as parameter for skip:
query.setSkip(count);
I have a ArrayList<String> -named listObjectId below- of objectIds. I'm trying to get all the objects that have an objectId contained in the ArrayList.
The solution I have right now, I think, is very bad from a performance point of view:
for (int i = 0; i < listObjectId.size(); i++) {
ItemModel mItemModelRetrieved = null;
ParseQuery<ItemModel > query = ParseQuery.getQuery(ItemModel .class);
try {
mItemModelRetrieved = query.get(listObjectId.get(i));
subscriber.onNext(mItemModelRetrieved ); //-- I'm using RxJava
} catch (ParseException e) {
Log.e(TAG, "Error Local " + e.getMessage());
}
}
You're using the wrong method. You have the object ids, so create a ParseObject with them using ParseObject.createWithoutData and then fetch the object. Try the following:
List<ParseObject> parseObjects = new ArrayList<>();
for (String objectId : listObjectId) {
parseObjects.add(ParseObject.createWithoutData(ItemModel.class, objectId));
}
ParseObject.fetchAll(parseObjects);
// parseObjects will now contain all data retrieved from Parse.
The error you're getting tells you that the data type of the column you query must be of type Array, not the value you pass into the method.
I am having some trouble getting some data from my Parse table/object with a query. I am trying to simply make a query which looks for the current Parse User's objectID in the "sender" column. When that result is returned, I want to extract the receiver's objectID from the "receiver" column associated with the user that I searched for. I keep getting 0 results, even though I know the data is there. Here is my code:
private List<String> potentialRelationQuery() {
mPotentialRelations = new ArrayList<>();
String currentUserId = mCurrentUser.getObjectId();
ParseQuery<ParseObject> query3 = ParseQuery.getQuery("PotentialRelation");
query3.whereEqualTo("sender", currentUserId);
query3.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> parseObjects, ParseException e) {
if (e == null) {
if (parseObjects.size() > 0) {
for (int i = 0; i < parseObjects.size(); i++) {
ParseUser receiver = (ParseUser) parseObjects.get(i).get("receiver");
String receiverId = receiver.getObjectId();
mPotentialRelations.add(receiverId);
}
}
} else {
Log.d("MyApp", "No matching objects returned from request");
}
}
});
return mPotentialRelations;
}
Since findInBackground is an asynchronous call to Parse isn't it possible that mPotentialRelations returns empty because the findInBackground query hasn't yet completed before the potentialRelationQuery method returns? I know I've had issues with this. Since you can't return data from an inner class (i.e. in the done method of FindCallback), writing this kind of query method has never really worked consistently for me.
I am new to parse data from parse.com.I am trying to update a column.The column in parse table is of array type.I am trying to add a value in array.For Example :
it is showing in data browser like this:
["Ado", "Wassja", "Cristi_3"]
And I want to add "ABC" value in this array programmatically like this:
["Ado", "Wassja", "Cristi_3","ABC"]
I have searched for this and got to know that first I need to fetch all the data of that particular row which I have to update ,then put the data in array I have fetch successfully the data for that particular row like this:
ParseQuery<ParseObject> query = ParseQuery.getQuery("UserMaster");
query.whereEqualTo("userName",str_uname2);
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> userList, ParseException e) {
dlg.dismiss();
if (e == null) {
if (userList.size()>0) {
for (int i = 0; i < userList.size(); i++) {
ParseObject p = userList.get(i);
str_dbpassword = p.getString("password");
String email = p.getString("email");
List<ParseObject> mfollowers = p.getList("followers");
List<ParseObject> mfollowing = p.getList("following");
ParseFile pp = (ParseFile)p.get("photo");
str_dbuname = p.getString("userName");
}
Log.d("password", "Retrieved " +str_dbpassword +"<uname>"+str_dbuname);
}
}
else {
Alert.alertOneBtn(LoginActivity.this,"Something went wrong!");
}
}
});
Now I have to update data in
List<ParseObject> mfollowers = p.getList("followers");
And
List<ParseObject> mfollowing = p.getList("following");
I don't know how to do this.Please help me.Your small clue will be very helpful.
Per the docs: http://parse.com/docs/android/api/com/parse/ParseObject.html
You can use add, addUnique, addAll, or addAllUnique to add elements to an array on a Parse Object:
someParseObject.add("arrayColumn", "ABC");
someParseObject.saveEventually();
To expand on Fosco's answer:
ParseObject parseObject = new ParseObject("YOURCLASS");
String[] stringArray = ["Ado", "Wassja", "Cristi_3"];
List<String> stringArrayList = new ArrayList(Arrays.asList(stringArray));
if (stringArray != null)parseObject.addAll("YOURCOLUMN", stringArrayList);
Make sure that the security settings for YOURCLASS enable you to create columns automatically or that you have the correct types set for your columns.
I hope that completes Fosco's answer.