Leave a rating/review
Notes: 08. Challenge: Request & Parse Data
The student materials have been reviewed and are updated as of July 2022.
To help you get a good understanding of Gson, parsing using libraries, and to repeat what you’ve learned about making requests using the HttpURLConnection, I’ve prepared a fun challenge for you!
In this challenge, you have to create an API call, to complete a note. You can once again find all the required information within the documentation for the server API.
Additionally, once you complete a note, you’ll see that you’re still receiving them through the getTasks endpoint.
For this reason, make sure you filter out completed notes, in the getTasks response.
That’s it! Now pause the video, and solve the challenge. Then once you’re done, unpause the video, and compare the two solutions. Good luck! :]
Start by heading over to the TaskOptionsDialogFragment.kt. Then add the network and threading checks, as you did with other requests:
private val networkStatusChecker by lazy {
NetworkStatusChecker(activity?.getSystemService(ConnectivityManager::class.java))
}
networkStatusChecker.performIfConnectedToInternet {
activity?.runOnUiThread {
...
}
}
This will take care of the threading and network checks. Then head over to the RemoteApi.kt, and add the following code to the completeTask call.
fun completeTask(taskId: String, onTaskCompleted: (Throwable?) -> Unit) { // added task ID
Thread(Runnable {
val connection = URL("$BASE_URL/api/note?id=$taskId").openConnection() as HttpURLConnection
Notice how you added the taskId parameter, to the function, so you can complete a specific task. You can easily copy and paste rest of the response parsing code, from one of the other calls. But make sure the endpoint path matches the following:
val connection = URL(
"$BASE_URL/api/note/complete?id=$taskId"
).openConnection() as HttpURLConnection
Thread(Runnable {
val connection = URL(
"$BASE_URL/api/note/complete?id=$taskId"
).openConnection() as HttpURLConnection
connection.requestMethod = "POST"
connection.setRequestProperty("Content-Type", "application/json")
connection.setRequestProperty("Accept", "application/json")
connection.setRequestProperty("Authorization", App.getToken())
connection.readTimeout = 10000
connection.connectTimeout = 10000
connection.doOutput = true
connection.doInput = true
try {
val reader = InputStreamReader(connection.inputStream)
reader.use { input ->
val response = StringBuilder()
val bufferedReader = BufferedReader(input)
bufferedReader.useLines { lines ->
lines.forEach {
response.append(it.trim())
}
}
onTaskCompleted(null)
}
} catch (error: Throwable) {
onTaskCompleted(error)
}
connection.disconnect()
}).start()
The important thing here is the API path. Notice the ?id=$taskId section. This is called a query. A query is just what the name states, a query of sorts, where you specify what exactly you want to do.
In this case, you want to complete the note, with the queried id. If you have chained queries, or queries with multiple parameters, it’d look something like this:
This query would compare both the taskId, and the noteTitle. Now that you’ve created this call, change the getTasks call in the end, to the following:
val unfinishedTasks = tasksResponse.notes.filter { !it.isCompleted }
onTasksReceived(unfinishedTasks, null)
This will filter out completed tasks, for UI display. Ideally, this would be done on the backend, or server, side, but in this case, you will do it yourself!
One more thing before running the project, head over to the TaskOptionsDialogFragment, and add the taskId argument to the completeTask function call. Now run the project! :]
Long click on a task, and select Complete. It should be removed from the list. Now restart the app, and you’ll see that it’s no longer there! Way to go!