Reading JSON using Kotlin - android-studio

I'd love to know what I'm doing wrong - can't access "links" on my JSON file.
Part of code (MainActivity.kt):
var arr = arrayListOf<String>()
fun read_json() {
var json : String? = null
try {
val inputStream:InputStream = assets.open("links.json")
json = inputStream.bufferedReader().use{it.readText()}
var jsonarr = JSONArray(json)
for (i in 0..jsonarr.length()-1){
var jsonobj = jsonarr.getJSONObject(i)
arr.add(jsonobj.getString("links"))
}
var adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, arr)
json_list.adapter = adapter
}
catch(e : IOException){
}
}
JSON file:
{
"links":
[
"google.com",
"youtube.com",
"facebook.com"
]
}
If I remake JSON file, so it will like in the following JSON file, everything works fine. However, I need to use the previous file. 😒
[
{
"links": "google.com"
}
]
Would really appreciate your help!

I believe you need to get the JSON array first and read strings from it, something like this:
var jsonarr = JSONObject(json).getJSONArray("links")
for (i in 0..jsonarr.length()-1) {
arr.add(jsonarr.getString(i))
}

Related

How do I access content from JSON string?

I am receiving a JSON object from the backend now I just want "result" array only in my template variable in my angular application from it.
{
"result":[
{"name":"Sunil Sahu",
"mobile":"1234567890",
"email":"abc#gmail.com",
"location":"Mumbai",
"Age":"19"
}
],
"status":200
}
Try with
variable_name["result"].
Try with
var data = response from the backend
var result = data.result;
$var = '{"result":[{"name":"Sunil Sahu","mobile":"1234567890","email":"abc#gmail.com","location":"Mumbai","Age":"19"}],"stats":200}';
If your $var is string, you need to turn it to "array" or "object" by json_decode() function
object:
$var_object = json_decode($var); //this will get an object
$result = $var_object->result; //$result is what you want to get
array:
$var_array = json_decode($var, true); //this will get an array
$result = $var_array['result']; //$result is what you want to get
Else if $var is object, direct use
$result = $var->result; //$result is what you want to get
As result is an array of objects, you can either use any loop to extract key value pair or you can directly access the array using index value.
var results = data["result"] // this would return an array
angular.forEach(results, function(value, key) {
//access key value pair
});
For accessing results in HTML, ng-repeat directive can be used.
Your question didn't explain further, but in the simple way try this :
const stringJson = `{
"result":[
{"name":"Sunil Sahu",
"mobile":"1234567890",
"email":"abc#gmail.com",
"location":"Mumbai",
"Age":"19"
}
],
"status":200
}`
const obJson = JSON.parse(stringJson);
console.log(obJson.result);

Dynamic JSON in Terraform

I am using Terraform to Invoke a lambda function, and need to pass an input JSON which includes a list of string values.
data "aws_lambda_invocation" "invo6" {
function_name = "my_function"
input = <<JSON
{
"pairs":[
{
"principal":"arn:aws:iam::12345678901:role/myRole",
"databases":[
"my_db_apple", "my_db_banana", "my_db_orange"
]
}
]
}
JSON
}
Instead of hard-coding these database names, I want to pull in from a map that already exists elsewhere in my tf files.
variable "gluedb_map" {
type = map(map(string))
default = {
"apple" = {
description = "my apple db"
catalog = ""
location_uri = "s3://mybucket/"
params = ""
}
"banana" = {
description = "my banana db"
catalog = ""
location_uri = "s3://anotherpath/"
params = ""
}
I tried swapping out the 'databases' code for this :
input = <<JSON
{
"pairs":[
{
"principal":"arn:aws:iam::12345678901:role/myRole",
${jsonencode("databases": [for each in var.gluedb_map : "my_db_${each}"], )}
}
]
}
JSON
but i then get error :
A comma is required to separate each function argument from the next.
Can anyone spot where I'm going wrong ?
Thanks
If you're just interested in accessing the keys of the map then you can use the keys function to return a list of keys. You can then combine that with formatlist to interpolate each list item with a string.
I'd also recommend using a HCL map for the wider data structure and then encoding to JSON rather than trying to JSON encode a section of it and having to mangle things to get it in a suitable shape.
A fully worked example then looks something like this:
variable "gluedb_map" {
type = map(map(string))
default = {
"apple" = {
description = "my apple db"
catalog = ""
location_uri = "s3://mybucket/"
params = ""
}
"banana" = {
description = "my banana db"
catalog = ""
location_uri = "s3://anotherpath/"
params = ""
}
}
}
output "json" {
value = jsonencode({
pairs: [
{
principal = "arn:aws:iam::12345678901:role/myRole"
databases = formatlist("my_db_%s", keys(var.gluedb_map))
}
]
})
}
Applying this will output the following:
json = {"pairs":[{"databases":["my_db_apple","my_db_banana"],"principal":"arn:aws:iam::12345678901:role/myRole"}]}
You can try to use keys, formatlist and join to get:
${jsonencode("databases": [join("," , formatlist("my_db_%s", keys(var.gluedb_map)) )}

Best way to navigate throught a JSON in Node while validating the path

I'm trying to get some info out of a API call in Nodejs, structured something like a JSON:
{
"generated":"2019-11-04T09:34:11+00:00",
"event":{
"id":"19040956",
"start_":"2019-11-16T11:30:00+00:00",
"event_context":{
"sport":{
"id":"1",
"name":"Soccer"
}
}
}
}
I'm not sure about the presence of none of these fields(Json could be incomplete).
Is there a better way to get the value of "name" in JSON.event.event_context.sport.name without an ugly if to not get errors like "cannot get field 'sport' of undefined"?
Currently, I'm doing
if(json.event && json.event.event_context && json.event.event_context.sport) {
return json.event.event_context.sport.name;
}
Is there a better way?
Thank you!
what do you mean by saying "I'm not sure about the presence of none of these fields"?
i don't understand what your'e trying to achieve.
Looks like there is also an interesting package that will allow more conditions on searching json :
https://www.npmjs.com/package/jspath
let getNested = (path, obj) => {
return path.split(".").reduce( getPath, obj);
}
let getPath = (path, key) => {
return (path && path[key]) ? path[key] : null
}
let test = {
"foo": "bar",
"baz": { "one": 1, "two": ["to", "too", "two"] },
"event": { "event_context": { "sport": { "name": "soccer" } } }
}
console.log(getNested("none", test))
console.log(getNested("baz.one", test))
console.log(getNested("baz.two", test))
console.log(getNested("event.event_context.sport.name", test))
You can use lodash get to get a potentially deeply-nested value, and also specify a default in case it doesnt exist.
Example
const _ = require('lodash');
const my_object = {
"generated":"2019-11-04T09:34:11+00:00",
"event":{
"id":"19040956",
"start_":"2019-11-16T11:30:00+00:00",
"event_context":{
"sport":{
"id":"1",
"name":"Soccer"
}
}
};
_.get(my_object, 'event.event_context.sport.name'); // "Soccer"
_.get(my_object, 'event.event_context.sport.nonExistentField', 'default val'); // "default val"
Article: https://medium.com/#appi2393/lodash-get-or-result-f409e73e018b
You can check by using a function to check object keys like :
function checkProperty(checkObject, checkstring){
if(!checkstring)
return false;
var propertiesKeys = checkstring.split('.');
propertiesKeys.forEach(element => {
if(!checkObject|| !checkObject.hasOwnProperty(element)){
return false;
} else {
checkObject= checkObject[element];
}
})
return true;
};
var objectToCheck = {
"generated":"2019-11-04T09:34:11+00:00",
"event":{
"id":"19040956",
"start_":"2019-11-16T11:30:00+00:00",
"event_context":{
"sport":{
"id":"1",
"name":"Soccer"
}
}
}
}
if (checkProperty(objectToCheck ,'event.event_context.sport.name'))
console.log('object to find is : ', objectToCheck .event.event_context.sport.name;)
Yeah there are better ways!
For example, you could use lodash's get() method to reach a nested value.
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.get(object, 'a[0].b.c');
// => 3
But there is also a native solution.
Currently (11.2019) only Babel can handle this.
I am speaking of Optional chaining. It's new in the Ecmascript world.
Why I like it? Look here!
// Still checks for errors and is much more readable.
const nameLength = db?.user?.name?.length;
What happens when db, user, or name is undefined or null? With the optional chaining operator, JavaScript initializes nameLength to undefined instead of throwing an error.
If you are using Babel as a compiler then you could use it now.
Related link: https://v8.dev/features/optional-chaining

Getting a string from JSON object with args from another object

Say I have a JSON file like this:
{"ABCD":{
"1_99":{"type": 3, "serverPath": "http://some.website.com"}
},
"EFGH":{
"1_00":{"type": 2, "serverPath": "http://another.meme.website/"}
"1_01":{"type": 2, "serverPath": "http://yet.another.website.com/memes"}
},
etc..
}
and I want to reference one of the element in that file:
let appList = require('./config/appList.json');
...
var uri = appList.ABCD.1_99.serverPath;
where element name "ABCD" and "1_99" comes from another object and it's not always the same, say:
var uri = appList. [httpPOSTRequest.app_id] . [httpPOSTRequest.app_ver] . serverPath;
which I wonder if there's any way that can do so please.
You can loop through your appList or you can use other libraries like (https://lodash.com/). I have implemented it with simple loop
let appList = {
"ABCD": {
"1_99": {
"type": 3,
"serverPath": "http://some.website.com"
}
},
"EFGH": {
"1_00": {
"type": 2,
"serverPath": "http://another.meme.website/"
}
}
}
Object.keys(appList).map((d,i)=>{
Object.keys(appList[d]).map((data, index)=>{
console.log(`server path ${i} : ${appList[d][data].serverPath}`);
})
})
You can encapsulate your search properties in a search object, then use this to access your appList object using JavaScript bracket notation.
I've wrapped this up in a getServerPath function which also conveys the intent of the exercise.
We'll return null if we can't find the path in question.
Also, bear in mind, there is a very useful function in the lodash library _.get which can do an awful lot of this stuff for you, I've included an example below.
I hope this helps you!
// Get the required server path given the searchInput object
function getServerPath(appList, searchInput) {
if (!searchInput) return null;
if (!appList[searchInput.property1]) return null;
if (!appList[searchInput.property1][searchInput.property2]) return null;
return appList[searchInput.property1][searchInput.property2].serverPath;
}
// In Node.js we would use require('file.json') to define this.
let appList = {
"ABCD": {
"1_99": {
"type": 3,
"serverPath": "http://some.website.com"
}
},
"EFGH": {
"1_00": {
"type": 2,
"serverPath": "http://another.meme.website/"
}
}
}
// Search object input
let searchInput1 = { property1: "ABCD", property2: "1_99" };
let searchInput2 = { property1: "EFGH", property2: "1_00" };
let searchInput3 = { property1: "DOESNTEXIST", property2: "1_00" };
console.log("Server path 1:", getServerPath(appList, searchInput1));
console.log("Server path 2:", getServerPath(appList, searchInput2));
console.log("Server path 3:", getServerPath(appList, searchInput3));
// Using the very useful lodash _.get
console.log("Server path (using lodash _.get):", _.get(appList, "ABCD.1_99.serverPath"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Parse string (node js ) .Find array of numbers into string

\n54766392632990,178.32.243.13,wfsdsfsdfs23432,\n54766393632990,178.32.243.13,
Above u can see example of string which I want to parse.. I want to get array if numbers which exist between (\n....,178.32.243.13) .. In this example it will be smth like :
[54766392632990,54766393632990] - how to make it
Please run this script it full file your requirement
var ss = "\n54766392632990,178.32.243.13,wfsdsfsdfs23432,\n54766393632990,178.32.243.13,"
var ddd = ss.split(",")
console.log(ddd)
var dfd = []
ddd.forEach(function(res){
if(res.startsWith("\n"))
{
dfd.push(res.replace("\n",""))
}
})
console.log(dfd)
Result [ '54766392632990', '54766393632990' ]
"\n54766392632990,178.32.243.13,wfsdsfsdfs23432,\n54766393632990,178.32.243.13,"
.split("\n")
.filter((n)=> n!== "")
.map(n=> parseInt(n.split(",")[0]))
You can do something like this to parse this string
let s = "\n54766392632990,178.32.243.13,wfsdsfsdfs23432,\n54766393632990,178.32.243.13,"
s = s.split("\n");
let array = [];
for(let i=0;i<s.length;i++) {
let v = s[i].split(",178.32.243.13,");
for(let j=0;j<v.length;j++) {
if(!isNaN(parseInt(v[j]))) {
array.push(v[j]);
}
}
}
console.log(array);

Resources