I am new to flutter and want to parse the data from a URL that is in json format. The url that I am using is json link .
I want to get the "verse" and "chapter" fields from the json array. I have succeeded in getting the response body in snackbar but not able to get single values. I want to get the "verse" and "chapter" and show then in text box. I am using Dart.
Here is the method that I am using:
_makeGetRequest() async {
// make request
var url = Uri.parse("http://quotes.rest/bible/vod.json");
Response response = await http.get(url);
// sample info available in response
int statusCode = response.statusCode;
Map<String, String> headers = response.headers;
String contentType = headers['content-type'];
String json = response.body;
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(json)));
}
#override
void initState() {
super.initState();
streamingController.config(url: "http://stream.zeno.fm/qa8p6uz2tk8uv");
streamingController.play();
_makeGetRequest();
}
Please help me in getting the proper field values and set them in text box as I am trying to solve it from past two days and have tried all solutions from internet but getting exceptions.
use jsonDecode
Map<String,dynamic> data = jsonDecode(response.body);
String verse = data["contents"]["verse"];
dynamic chapter= data["contents"]["chapter"];
however I recommend modeling your data
Related
"Dart Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable' "
It says that the error is in the following line:
for(var jsonObject in jsonObjects){
objects.add(Object.fromJson(jsonObject));
}
For context, the entire code is this:
class _HomePageState extends State<HomePage> {
final List<Object> _objects = [];
Future<List<Object>> fetchData() async{
const String urlString = 'https://api.publicapis.org/entries';
final Uri url = Uri.parse(urlString);
var response = await http.get(url);
final List<Object> objects = [];
if(response.statusCode == 200){
var jsonObjects = json.decode(response.body);
print("Step 1");
for(var jsonObject in jsonObjects){
objects.add(Object.fromJson(jsonObject));
}
}
return objects;
}
Any help would be greatly appreciated. Thanks.
Main problem is that response.body is not a list of elements, and you are assuming it is. Instead of that, it's a "key" : "value" type of json object, which cannot be iterated.
The for (var e in collection) syntax is made to be used with an Iterable collection, and _InternalLinkedHashMap (and maps in general) are not iterables.
The solution is to parse the response properly. Check this link if you want to follow best practices for flutter development json parsing.
Your api response's body is a Map:
{"count":1425,
"entries":[
{"API":"AdoptAPet","Description":"Resource to help get pets adopted","Auth":"apiKey","HTTPS":true,"Cors":"yes","Link":"https://www.adoptapet.com/public/apis/pet_list.html","Category":"Animals"},
{"API":"Axolotl","Description":"Collection of axolotl pictures and facts","Auth":"","HTTPS":true,"Cors":"no","Link":"https://theaxolotlapi.netlify.app/","Category":"Animals"},
...
]
}
what you are looking for is a list, Try this:
var jsonObjects = json.decode(response.body["entries"]);
print("Step 1");
for(var jsonObject in jsonObjects){
objects.add(Object.fromJson(jsonObject));
}
I'm getting the json data from the API call but its not displaying the complete data.There are a lot of properties to work with and creating the model would be difficult as it's my first time working on any API.So i wanted to use app.quicktype.io to parse the json data directly into dart code for which i need to get the complete json data.Right now only little bit of the json data is being displayed in the console.
CODE:
Future<void> getContacts() async {
var client = http.Client();
String contacts_url =
'https://mylinkexample.com';
String basicAuth =
'Basic mykeyexampele';
var response = await client.get(contacts_url,
headers: <String, String>{'authorization': basicAuth});
var jsonString = jsonDecode(response.body);
print(response.statusCode);
print(jsonString);
}
Use this :
import 'dart:developer' as developer;
test() {
developer.log(response.body);
}
I've managed to extract data from a POST method in hyper using the following:
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Method, Request, Response, Server};
use std::convert::Infallible;
use std::net::SocketAddr;
use tokio;
async fn handle(_req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
match (_req.method(), _req.uri().path()) {
(&Method::GET, "/") => Ok(Response::new(Body::from("this is a get"))),
(&Method::POST, "/") => {
let byte_stream = hyper::body::to_bytes(_req).await?;
let _params = form_urlencoded::parse(&byte_stream)
.into_owned()
.collect::<HashMap<String, String>>();
However, the whole JSON body is just one key in the HashMap now. How do I split it up so I have a hashmap with multiple keys and values as opposed to one key that's the entire body?
[dependencies]
futures = "0.1"
hyper = "0.13"
pretty_env_logger = "0.3.1"
url = "2.1.1"
tokio = { version = "0.2", features = ["macros", "tcp"] }
bytes = "0.5"
There is a discrepancy between your description:
However, the whole JSON body
And your code:
let _params = form_urlencoded::parse(&byte_stream)
If your data is JSON then parse it as JSON, using the serde_json crate:
let _params: HashMap<String, String> = serde_json::from_slice(&byte_stream).unwrap();
I am looking for some help with a datatable conversion into a JObject. I am using C# in visual studio along with the Newtonsoft JSON .net library. I have retrieved my datatable from my database.
From here I took the data table and processed it through this class:
public string DataTableToJSONString(DataTable table)
{
string JSONString = string.Empty;
JSONString = JsonConvert.SerializeObject(table,Formatting.Indented);
return JSONString;
}
Now that the object has been converted to a JSONString successfully (It throws no errors at this point) via the Newtonsoft JSON.net Library, I am unable to parse it into a JObject with this code:
Note: "json" is the string variable I placed the returned value from the DatatabletoDataTableToJSONString() method into..
JObject job = JObject.Parse(json);
I continuously get the following error...
Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.
The reason I need it in the form of a JObject it to pass it into the following post method for an API:
public static async Task<JObject> Post(string url, JObject data)
{
// Create an HttpClient instance
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = CreateBasicHeader(ClientContext.Username, ClientContext.Password);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Send a request asynchronously and continue when complete
var requestbody = new StringContent(data.ToString(), Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(url, requestbody);
dynamic content = await response.Content.ReadAsAsync<JObject>();
// Check that response was successful or throw exception
try
{
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
throw new Exception("Status Code: " + response.StatusCode + "\r\nMessage: " + content[0].ToString(), ex);
}
// Read response asynchronously as a JObject
return content;
}
I would appreciate any help on this as I have been researching for 2 weeks with no luck. This one is really killing me. Thanks in advance to all who take the time to examine this.
UPDATE: I ended up adding in the following bit of code as I realized I was returning an array when I pulled the data table.
string jsonresult = JsonConvert.SerializeObject(dt);
JArray aray = JArray.Parse(jsonresult);
//I then have code for the API login credentials here....
foreach (JObject item in aray)
{
ApiClient.Post(Url, item).Wait();
}
This appears to pass in the JObjects just fine into the post method although I get the following error:"AggregateException was unhandled..." I set a break point and the flaw appears to happen at the:
try
{
response.EnsureSuccessStatusCode();
}
After attempting the response.ensuresuccessstatusCode(); The program of course jumps to the catch....
catch (Exception ex)
{
throw new Exception("Status Code: " + response.StatusCode + "\r\nMessage: " + content.message.ToString(), ex);
}
Again, any help would be appreciated. I am almost there with this. After it posts, I will be done.... Thanks again in advance to everyone. I apologize for being long winded.
Your problem is that JSON has two types of containers: arrays and objects:
An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace).
The corresponding LINQ to JSON class is JObject.
An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).
The corresponding LINQ to JSON class is JArray.
So, how does Json.NET serialize a data table? From the documentation Serialize a DataSet, we can see that each table is serialized as an array.
If you attempt to parse a JSON string whose root object is an array into a JObject, you will get this exception.
Instead, you must return a JArray, or better yet a JToken which is the root class for all JSON entities:
public static async Task<JToken> Post(string url, JObject data)
{
// Create an HttpClient instance
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = CreateBasicHeader(ClientContext.Username, ClientContext.Password);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Send a request asynchronously and continue when complete
var requestbody = new StringContent(data.ToString(), Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(url, requestbody);
dynamic content = await response.Content.ReadAsAsync<JToken>();
// Check that response was successful or throw exception
try
{
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
throw new Exception("Status Code: " + response.StatusCode + "\r\nMessage: " + content[0].ToString(), ex);
}
// Read response asynchronously as a JToken
return content;
}
I am answering this thread and closing it as the original question has technically been answered. I simply converted the JArray into its respective JObjects with the following bit of code.
foreach (JObject item in aray)
{
ApiClient.Post(Url, item).Wait();
}
Although I am still working on debugging, I was technically able to pull the Object out of the array that I got from the data table.
Thanks all!!!!!
I'm having a bit of trouble parsing the JSON response from YouTube but I need a bit of assistance doing so. I'm attempting to obtain the fields: id, videoId, thumbnails and url - using the following:
private String getUrl(String id) throws IOException, JSONException {
HttpClient client = new DefaultHttpClient();
HttpGet clientGetMethod = new HttpGet(YOUTUBE_INFO_URL.replace("_ID_", id));
HttpResponse clientResponse = null;
clientResponse = client.execute(clientGetMethod);
String infoString = _convertStreamToString(clientResponse.getEntity().getContent());
String urldata=new JSONObject(infoString).getJSONObject("id").getJSONObject("videoId").getJSONArray("thumbnails").getJSONObject(0).getString("url");
return new JSONObject(infoString).getJSONObject("id").getJSONObject("videoId").getJSONArray("thumbnails").getJSONObject(0).getString("url");
}
YouTube API v3 Response:
http://pastebin.com/LKWC2Cbz
However I continually get fatal errors due to incorrect parsing. Can someone spot where I may have gone wrong? I'm specifying the fields I need - however I feel like the structure must not match the JSON response in some manner.
So I assume that infoString contains the JSON response that you pasted to the pastebin link you shared.
This is my first Java program and I'm using Java 8 so things are a little bit different than in your code (I'm using JsonObject for example, not JSONObject, although when reading the program it should be clear what you need to modify)
package stackoverflowyoutubejson;
import java.io.IOException;
import javax.json.*;
public class StackOverflowYoutubeJson {
public static void main(String[] args) {
try {
JsonObject object;
// Instead of making a Http GET request I just read out the JSON file's contents saved down locally
try (JsonReader jsonReader = Json.createReader(StackOverflowYoutubeJson.class.getResourceAsStream("input/youtube-response.json"))) {
object = jsonReader.readObject();
}
// Obtaining the items array
JsonArray items = object.getJsonArray("items");
// Iterating the items array
for(int i = 0; i < items.size(); i++) {
JsonObject item = items.getJsonObject(i);
JsonString id = item.getJsonString("id");
System.out.println("id: " + id);
JsonObject snippet = item.getJsonObject("snippet");
JsonString videoId = snippet.getJsonObject("resourceId").getJsonString("videoId");
System.out.println("videoid: " + videoId);
JsonString url = snippet.getJsonObject("thumbnails").getJsonObject("default").getJsonString("url");
System.out.println("default thumbnail url: " + url);
System.out.println();
}
}
catch(IOException e) {
System.out.println(e);
}
}
}
The output of this program is:
id: "PL7ztmfZ6VHFYVLwdKgxI9lwOWFV_yoCFOK5o9K8KSE2s"
videoid: "PcfLDmkpzto"
default thumbnail url: "https://i.ytimg.com/vi/PcfLDmkpzto/default.jpg"
id: "PL7ztmfZ6VHFYVLwdKgxI9l7VIO-rUMLOT7pjiYSbTRPw"
videoid: "D9ohtWGSl9M"
default thumbnail url: "https://i.ytimg.com/vi/D9ohtWGSl9M/default.jpg"
id: "PL7ztmfZ6VHFYVLwdKgxI9l5gWA-vAfTbxQVrUWaMILLA"
videoid: "B1OluIUHLnY"
default thumbnail url: "https://i.ytimg.com/vi/B1OluIUHLnY/default.jpg"
id: "PL7ztmfZ6VHFYVLwdKgxI9l9A2H_-9HSzVlvT--kLf0TA"
videoid: "LjKpcUJSjtM"
default thumbnail url: "https://i.ytimg.com/vi/LjKpcUJSjtM/default.jpg"
id: "PL7ztmfZ6VHFYVLwdKgxI9l9nWIbKA-8Bnu3v_D6xEKaU"
videoid: "fTSmcQdLyhU"
default thumbnail url: "https://i.ytimg.com/vi/fTSmcQdLyhU/default.jpg"
So basically, if you have a JSON like this:
{
"field1": {
"nestedField1": "nestedValue1",
"nestedField2": "nestedValue2"
},
"field2": "value2"
}
You can access the fields like this:
JSONObject wholeJson = new JSONObject(jsonStringAsDescribedAbove);
JSONString field2 = wholeJson.getJSONString("field2"); // will contain value2
JSONObject field1 = wholeJson.getJSONObject("field1"); // will contain the whole field1 object
JSONString nestedField1 = wholeJson.getJSONObject("field1").getJSONString("nestedField1"); // or field1.getJSONString("nestedField1");, will contain nestedValue1
JSONString nestedField2 = wholeJson.getJSONObject("field1").getJSONString("nestedField2"); // or field1.getJSONString("nestedField2");, will contain nestedValue2