Flask REST API responding with a JSONArray - android

I have created a simple REST API using Flask for an Android application. I'm having trouble implementing the GET method. It is supposed to return all the records in the form of a JSONArray. The response would look something like his
{
"tasks": [{
"task" : "Do it",
"timestamp": 1433510946152
},{..}
],
"success": 1
}
My Task model looks like this
class Task(db.Model):
id = db.Column(db.Integer, primary_key=True)
task= db.Column(db.Text, nullable=False)
timestamp = db.Column(db.Integer, nullable=False)
#staticmethod
def newest():
return Task.query.order_by(desc(Task.timestamp))
def to_json(self):
return dict(id=self.id,
task= self.task,
timestamp = self.timestamp)
The to_json() method converts the result into JSON. I just don't know how to use it appropriately. How would I put all the records inside of an JSONArray? Here is my method that gets all the tasks. I'm using Flask paginate too, so tasks is a pagination object.
def get_tasks():
page = request.args.get('page')
if page is not None:
try:
page = int(request.args.get('page'))
except:
return jsonify({'result': 'Invalid parameter'})
else:
page = 1
tasks= models.Task.newest().paginate(page, 7, True)
#How do I return the tasks in an appropriate format?
Any help would be appreciated. Thanks.

Simply loop over your tasks, convert them into json using your to_json and store them inside of an array. For example:
def get_tasks():
page = request.args.get('page')
if page is not None:
try:
page = int(request.args.get('page'))
except:
return jsonify({'result': 'Invalid parameter'})
else:
page = 1
tasks= models.Task.newest().paginate(page, 7, True)
# This list will hold all your tasks in JSON format
jsontasks = []
# Since tasks is a pagination object, you should use tasks.items
for task in tasks.items:
jsontasks.append(task.to_json())
#How do I return the tasks in an appropriate format? Like this..
return jsonify({'tasks': jsontasks, 'success': 1})

Related

Using .addOnSuccessListener to return a value for a private method

Good day. Is there some way that I could implement this one?
val db = Firebase.firestore
val userID = Firebase.auth.currentUser!!.uid
val infoRef = db.collection("user").document(userID).collection("profile").document("info")
infoRef.get()
.addOnSuccessListener {document ->
if(document != null){
//get the data as cast to hashmap
val data = document.data as HashMap<*, *>
//get the username field and set text for greet user as the same value inside firestore
val username = data["username"] as String
tv_greet_user.text = "Hello, $username"
}
}
//extract the code above as a new method called "getUsername()"
val username : String = getUsername()
tv_greet_user.text = "Hello, $username"
Yes, you can create a function that looks like this:
fun getUsername(data: HashMap<String, Any>) = data["username"] as String
And inside your callback simply call:
val username = getUsername(data)
Is there a way to extract the whole block into a separate method? So that in the onCreate method, I could simply change the TextView into something like: val username = getUsername() tv_greet_user.text = "Hello, $username"
Edit:
As also Frank van Puffelen mentioned in his you cannot return the result of an asynchronous operation as a result of a method. Since you are using Kotlin programming, please note that there is actually o solution. I wrote an article called:
How to read data from Cloud Firestore using get()?
In which I explained four ways in which you can get data from Firestore. So if you are willing to use Kotlin Coroutines, then things will be much simpler.
Data is loaded from Firestore (and most modern web/cloud APIs) asynchronously. Since it may take some time before the data is available, your main code continues running while the data is being loaded. Then when the data is available, your success listener callback is called with that data.
This unfortunately means that it is impossible to return the value from the database in a function, because by the time the return statement runs, the data hasn't been loaded yet.
And that's also precisely why infoRef.get() in your code doesn't simply return the value from the database, but requires that you pass in a callback function that it invokes when the database is available. Sure, your code would be a lot simpler if get() would immediately return the value from the database, but it can't do that because the data needs to be loaded from the network.
I recommend reading:
The Kotlin docs on asynchronous programming techniques
Why does my function that calls an API return an empty or null value?
How to return a DocumentSnapShot as a result of a method?
How to check a certain data already exists in firestore or not

Query Data from Google Spreadsheet in Android

I am trying to query data form Google Spreadsheet available to be read by anyone with the Read Only link.
I implemented this Quickstart solution but here is what I need:
Access data just with URL, no authentication needed
Query item in column A and get value in column B
No need for updating any data
I tried constructing queries like:
http://spreadsheets.google.com/tq?tq=SELECT%20*%20WHERE%20A=C298732300456446&key=2aEqgR1CDJF5Luib-uTL0yKLuDjcTm0pOIZeCf9Sr0wAL0yK
But all I get is:
/*O_o*/
google.visualization.Query.setResponse(
{
"version": "0.6",
"reqId": "0",
"status": "error",
"errors": [
{
"reason": "invalid_query",
"message": "INVALID_QUERY",
"detailed_message": "Invalid query: NO_COLUMN: C298732300456446"
}
]
}
This comes when the data is actually present in the sheet in column A with value C298732300456446.
What can I do for getting the data, without any authentication from my spreadsheet?
I am not sure if this can be done. If fine, I can suggest an alternative solution. You can try writing a Google App script like:
function doGet(e) { return getInfo(e); }
function doPost(e) { return getInfo(e); }
function getInfo(request) {
var someValueFromUrl = request.parameter.value;
var requiredValue = "";
var sheet = SpreadsheetApp.openById("spreadsheet_id");
var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i++) {
Logger.log("Reading row num: " + i);
if(data[i][0] == someValueFromUrl) {
requiredValue = data[i][1];
break;
}
}
Logger.log(requiredValue);
return ContentService.createTextOutput(JSON.stringify(requiredValue));
}
This way, you can publish this script as web app and call it using an URL which will be obtained when you publish this script.
Call the script like:
https://script.google.com/macros/s/obtained_url/exec?value=1234
If key is found, you will get the String response as:
"value"
I hope this helps.
C298732300456446 needs to be put within single quotes.
So you need to enclose C298732300456446 as %27C298732300456446%27
Your'e modified query would be
http://spreadsheets.google.com/tq?tq=SELECT%20*%20WHERE%20A=%27C298732300456446%27&key=2aEqgR1CDJF5Luib-uTL0yKLuDjcTm0pOIZeCf9Sr0wAL0yK
I'm unable to test this though - looks like you've removed/removed access from this spreadsheet.

Parse Server Android SDK query retrieves list of empty values

I am using self hosted Parse server (Using Ubuntu Server). For my Android app, have following dependencies,
****compile 'com.parse.bolts:bolts-tasks:1.3.0'
compile 'com.parse:parse-android:1.13.1'****
I am able to save the data in cloud. The problem is when I try to retrieve the data its giving list of data (eg. list of 10 objects). But its fields didn't have the actual value that I have saved. Its shows the default value of the field type (eg. String = null, int = 0, double = 0.0)
Example Saving Data
Rich {
String name = "UserName",
int age = 22,
double weight = 58
}
Example Retrieved Data
[
Rich {
name = null,
age = 0,
weight = 0.0
},
...
...
]
I am querying as follows
ParseQuery<ParseObject> query = ParseQuery.getQuery("Rich");
List list = query.find();
If you guys know about the issue, please tell me what I am doing wrong.
Thanks in advance.

How to recognize if json key value is unavailable?

JSON for Example:
{
"example_key1": {
"one": 1,
"two": 2,
"three": 3
},
"example_key2": [
{
"four": 4,
"five": 5,
"six": 6
}
]
}
Right now i am consuming one method from web service.That method is returning some JSON data like the above JSON example.
Here my problem is if some KEY values is missing from the JSON data, after consuming that method.(Say "example_key2" json value from the above json example is missing)
in the sense,
how can i recognize wether that key value is available or not?
You can check whether particular key is available or not by using has() method
For example:
if(myJSONObject.has("one")) {
num = myJSONObject.optString("one");
}
Use has method of JSONObject class
http://developer.android.com/reference/org/json/JSONObject.html#has(java.lang.String)
Returns true if this object has a mapping for name. The mapping may be NULL.
JSONObject j = new JSONObject("");
j.has("example_key2");

Why does ASP MVC create a JSON format Android doesn't like?

I have a very basic ASP MVC application exposing a static list of publications (see code and result below).
Code:
public JsonResult Index()
{
List<Publication> list = new List<Publication>() {
new Publication() { Id = 1, Name = "War and Peace" },
new Publication() { Id = 2, Name = "Harry Potter" },
new Publication() { Id = 3, Name = "Cat in the Hat" }
};
return this.Json(list, JsonRequestBehavior.AllowGet);
}
Result:
[{"Id":1,"Name":"War and Peace"},{"Id":2,"Name":"Harry Potter"},{"Id":3,"Name":"Cat in the Hat"}]
When I attempt to consume it in Android I get the following error:
04-15 12:00:57.331: W/System.err(209): org.json.JSONException: A JSONObject text must begin with '{' at character 1 of [{"Id":1,"Name":"War and Peace"},{"Id":2,"Name":"Harry Potter"},{"Id":3,"Name":"Cat in the Hat"}]
I can remove the starting [ and ending ] and it stops the error from appearing. The other option is to put the { publications: logic at the beginning of the android code, but that seems like it should already be there.
How can I update the code in the MVC application to produce a "ready to be consumed" version of JSON?
Any help is greatly appreciated.
First, you shouldn't modify your json string when received, because it may mess up with the parsing.
Second, your Json string is in array format because it starts with [ and ends with ]. So, instead of using JSONObject, you should use JSONArray.
I recommend to use GSON. It's simple to use, fast and accurate.

Categories

Resources