How to get value from map object in dart - dart

I have a Map object
Map decodedresp = json.decode(response);
from here i get a list :
print(decodedresp['objectUrls']);
[{signedUrl: abc.com, path: a/b/c.log}]
now I want to get abc.com in a string, and I am not able to get it
I am learning dart and I am new to it

So, from what I can see it looks like you're dealing with parsed json.
In decoding json like you did json.decode(response) you're getting a:
_InternalLinkedHashMap<String, dynamic>
From that you are accessing objectUrls which returns a List<Map>. In order to deal with that you need to look for the key which in this case is signedUrl or path. Because your Map is wrapped in a List you need to get the element of the List.
This should work for you
Map<String, dynamic> decodresp = json.decode(response);
List<dynamic> objectUrls = decoderesp['objectUrls'];
// Zero here to get the first element, followed by the key.
var signedUrl = objectUrls[0]["signedUrl"];
var path = objectUrls[0]["path"];
You can see it working here
I could be wrong but because there isn't much info this is what I'm going with.
Let me know if you have any problems.
Felix.

Related

Cannot assign value of type 'Dictionary<String?, String?>.Keys' to type 'String'

Here I have a database, which I want to easily use for my table view. However, I can't reach the properties, because I don't know how to assign from a dictionary to a string. It tells me:
Cannot assign value of type 'Dictionary.Keys' to
type 'String'
import Foundation
struct Test {
var title: String
var tagPreview: Tagpreview
}
struct Tagpreview {
var tag: [String?:String?]
}
var cases = [
Test(title: "title1", tagPreview: Tagpreview(tag: ["tag1": "preview1"])),
Test(title: "title2", tagPreview: Tagpreview(tag: ["tag2": nil])),
Test(title: "title3", tagPreview: Tagpreview(tag: [nil: nil])),
Test(title: "title4", tagPreview: Tagpreview(tag: ["tag4": "preview4", "tag5": nil]))
]
I want to use the keys and the values from the dictionary in the second struct to populate the text labels later in a cell:
cell.titleLabel?.text = cases[indexPath.row].tag.preview.keys //ERROR
cell.textLabel?.text = cases[indexPath.row].tag.preview.values//ERROR
There is something about dictionaries that I can't find anywhere as well as a comprehensive solution for this issue.
Now, if you know another way how to populate them easily, I'd much appreciate that! Thank you a lot in advance and have a good day!
The error you are receiving is due to Dictionary.keys returning a collection of the Type you selected as key. In your case the call cases[indexPath.row].tag.preview.keys returns a Collection of String? (similar to [String?])
Now if you wish to access a specific value from this collection, you should be able to do so like this:
let someText = cases[indexPath.row].tagPreview.tag.keys.map{ $0 }[someIndex]
Note that the use of map(). It merely converts the Strings collection to an Array of Strings, whose index is Int, thus making it easier to access the individual elements (otherwise you'd need abit more general/cumbersome iteration API of Collection).
Just side comment, it seems a bit difficult to extract data and map it directly to the view, if you intend to use such mapping many places it may pay out to have some intermediate data types which are easier to use when presenting; it really depends on your preference and the overall problem.

Dart: getElementsByClassName returns a 0 element list but the data is there

I'm writing a function that will parse certain websites and fetch data from there, which will be used to create instances of a class. I'm able to successfully extract the data when it is retrieved using the getElementById() function, but for some reason, the getElementsByClassName() always returns a node list with 0 elements.
The site I'm currently parsing is here.
If you search for 'datas-nev', you will find exactly one match:
<p class="datas-nev"><b>Kutya neve: </b>Jhonny</p>
And here is the code use for parsing:
import 'package:html/parser.dart' show parse;
...
final response = await http.get(URL);
var document = parse(response.body);
var detailsContainer = document.getElementById('husky_details_container_right');
var dogName = new List<Node>();
dogName = document.getElementsByClassName('datas-nev');
The contents of the detailsContainer can be extracted successfully, for example this gives me back a string of relevant data I will use later:
var humanBehaviourValue;
try { humanBehaviourValue = detailsContainer.nodes[1].nodes[19].nodes[1].nodes[7].nodes[1].toString(); }
catch (e) { humanBehaviourValue = 'N/A'; }
But when I check the value of dogName in the debug window, I get the following:
dogName = {_growableList} size = 0
I already tried initializing the dogName 'properly' by List<Node> dogName = new List<Node>(); but it didn't help. I also tried other datas-* values, but it seems the parser can't find them. I even tried using just datas (because that is a div, while others are paragraphs), but that didn't help either.
Basically I could just hardwire the name and some data (breed, color, etc) as those never really change, but the location of the shelter can change, and keeping it up-to-date by scraping the data seems better than pushing updates out manually. That means I mostly need the value of datas-helyszin but that isn't parsed either.
As #Günter Zöchbauer pointed out, the code actually works. I was just looking for the value too soon, before it was actually fetched...

Map json input but not output in Suave

Suave.Json.mapJson maps the input JSON to an object into your function, then maps the output of your function into JSON.
The problem is that I'm happy with the way it maps into my function, but I need to return a json string response rather than have suave serialise my output into JSON for me. How can I do this?
Currently i'm getting my output serialised twice. My code so far:
let executeQuery : Query -> string = //Query is my deserialised json input, the return value is a json string
let app = POST >=> path "/graphql" >=> Json.mapJson executeQuery >=> setMimeType "application/json; charset=utf-8"
startWebServer defaultConfig app
If you look at the Suave source code, you'll see that mapJson is shorthand for mapJsonWith fromJson toJson. The fromJson and toJson functions are the default JSON deserializer and serializer (respectively), but you could create your own instead -- or just use id to say "map this direction without changing it". E.g.,
let oneWayMapJson = mapJsonWith fromJson id
Note that I haven't tested this, just typed it into the Stack Overflow answer box, so some tweaking may be required. I don't have time to expand on this answer right now, but if you need more help than this rather barebones answer, let me know and I'll try to give you more help sometime tomorrow.

URL Mapping - Replacing characters in a parameter pulled from a database

I am currently trying to figure out, how to modify the parameter being integrated into the URL Mapping I am using.
static mappings =
{
"/$controller/$action?/$id?/(.$format)?"
{
constraints {
// apply constraints here
}
}
name test1: "/.../$title/..."{
controller = "study"
action = "st_show"
}
name test2: "/.../$title/..."{
controller = "search"
action = "se_show"
}
The parameter $title is pretty much a dataset, which is pulled from a database and which will get transmitted in the following format [ this is a title ]. So there are square brackets in front and behind the string and words are seperated through blanks.
If I am creating a link through g:link now with the params nested in, it gets put into the url as it is pulled from the database. What I am attempting is to create SEO-URLs, which will present a certain title of a publication devided by hyphens instead of url-encoded "%20".
Until now, I was able to generate dynamic urls looking like this:
http://localhost:8080/projectname/show/%5BAllgemeine%20Bevölkerungs[...]/782/...PARAMS...
Furthermore I already implemented it through JQuery, though it should be static and users should be able to copy the link to open up the page themselves - that wouldn't be possible when changing the url client-side while loading up the page.
Is there a way to define a function with something like replaceAll.(' ', '-'), which can be invoked onto the parameter in the mapping to replace blanks with hyphens and f.e. square brackets with an empty character?
That's pretty much, what I wasn't able to come by through the documentation.
Thank you already in advance for your help!
I managed to solve my problem by creating a service with a function containing a regex and executing this function onto the parameter title in my g:link, which I firstly converted to a string, which gets passed to the function.
<g:link controller="study" action="st_show" params="[data: data, ... title: ConversionService.convert(fieldValue(bean: path).toString(), ... data: data)]"></g:link>
And the function in the ConversionService
public static String convert(String title){
title = title.replaceAll("\\s", "-").replaceAll("[^0-9a-zA-Z\\-]", "");
return title;
}

Anyway can I extract filter segment from EntityQuery?

I am building EntityQuery.
Now I would like to get filter segment out of it? I know toString() will give me human readable string, but I want actual filter string that will be sent to fetch data along with URL.
The following should do it:
var queryString: string = this._manager.metadataStore.toQueryString(query);
manager being your EntityManager and query being the EntityQuery.
Result
SomeEntity?$filter=FirstFilter%2Fany(x1%3A%20x1%2FLicenseTypeId%20ne%2016730)&$expand=FirstFilter%2CFirstFilter%2FPartners%2CAddresses&$inlinecount=allpages
and here is an alternative that I don't quite like as much:
var anotherway = query._toUri(manager.metadataStore);

Resources