Returning multiple maps in one variable - dictionary

I am working on a XML parser and I have the following problem :
I have this function which gather some tags value, for example movie title and release date :
func whatever() map[string]interface{} {
}
And I would like it to return something of this form :
[map[title:Movie01] map[title:Movie02]]
Without changing the return type.
All I have for now is :
map[title:Movie01]
And obviously I cannot have duplicate "title" key in one single map.
Can you help me on this ? It's been bothering me for a couple of hours now.

For the record then, as I mentioned in the comments you could try returning a slice of maps such as
func whatever() []map[string]interface{} {
}
Though depending on your data you might find a better solution in defining an appropriate struct for your domain and returning that.

Related

Update an object with notation with a parameter?

In my firebase i have a collection, inside there is a document, and inside there is an object :
object 1
key1:value
key2:value
key3:value
I would like to only update certain keys inside an object say
object1 - key1 and key2.
to do that, i need notation.
the problem is that I pass a parameter to the function that save :
function updateit(product,target)
{
db.collection("Stores").doc(target).update({
product
})
So here if I pass a product that contains only key 1, it will override the previous.
So, I tried to pass this object with notation :
product["product"+".title"] = "xxxxx"; // a new pair in product to pass
and it didn't work, it will save a new object (override) with fields like :
product
product.title=xxxxx
How should you do such a simple thing ?
ok obviously, this is the answer :
db.collection("Stores").doc(targetStore).update(
product // no {} around 'product', not as object!
)
see the comment that explains it all.

Get reactive value from subscription in meteor

In Meteor, how do I properly return a value from a property (in this case response) from a collection so that I can send it to a data propert? I have tried the following function:
Responses: function(answer) {
return Responses.findOne({answerId: answer.hash.answer});
}
Which I call in the spacebars template as:
data-selected="{{Responses answer=_id}}
When I look at the HTML it says that the data-selected="[object object]" which is not super surprising but I can't figure out how to return just the response value from the match. I can add .response onto the end and it works but gives an expected 'undefined' error I know that it is not reactive. I have seen people use wrapasync but that was for methods, not subscriptions. I should note that there are several responses, so the code would have to be suitable inside a #for loop of answers which the responses variable is keeping track of the input from each user separately.
Thanks!
I'm not sure about data-selected="{{Responses answer=_id}}". Since you're already inside a for loop your html code can simply look like this:
data-selected="{{Responses}}"
Inside your helper function you can then say:
var myResponse = Responses.findOne({answerId: this._id}).response;
if (myResponse != null){
return myResponse;
else {
return "";
}
When the page is still loading and the data is not yet available, myResponse is still null, so the helper returns the empty string "". Shortly thereafter the data becomes available and your data gets returned, without any error in your console.

How do I type a function with input and output objects with the same keys but different value types?

Basically, I have a function that will transform an object into a different object, and it's like a dictionary, but I don't know how to type it.
var myFunctions = {
a: () => something1,
b: () => something2,
[...]
}
gets transformed into
var myObject = {
a: something1,
b: something2
[...]
}
With Flow 0.33+ you can use $ObjMap
type ExtractCodomain = <V>(v: () => V) => V;
declare function f<O>(o: O): $ObjMap<O, ExtractCodomain>;
I don't think you can do this with Flow. The closest you can get is probably this:
function<T>(obj: T): ([key: $Keys<T>]: boolean)
That function is typed to return an object with the same key as input object, but with boolean-only values (as an example, you can specify another type). Sorry to disappoint, but it's hard to type highly dynamic code with Flow in general.
Note that the $Keys feature is undocumented because it's not part of the public API, so its behavior is defined solely by its implementation (in other words, it can change anytime).
If you're interested in the details of Flow's type system, check out the typings that come with flow in its own /lib directory, for example https://github.com/facebook/flow/blob/master/lib/core.js – you'll see that some things like Object.assign are special-cased, so you might not be able to re-implement such things in your own code.
Also, check out http://sitr.us/2015/05/31/advanced-features-in-flow.html for other "dollar features" such as $Shape and $Diff – it's partially outdated, but can give some good pointers.
#Nikita gave you the best answer for now. That said, the use-case you talked about is being discussed in the issues on the FlowType repository. It may land soon.
As of right now, if you've got mixed type, I'll just fallback to any
function<T>(obj: T): ([key: $Keys<T>]: any)
This way, at least the key names are validated. I expect within a few more versions of Flow, this problem will get solved.

IncludeKeys in PFQuery not returning all relational data

I am using PFQueryTableViewController to retrieve objects from Parse. This particular Parse class has three columns (group, category, client) which are pointers to other Parse classes. I want to use the includeKey option to bring in all object data for each of those pointer objects. However, when I run the code below, I do retrieve the basic data about each pointer column (like ObjectID), but none of the additional columns, like the "name" column of the Category class.
override func queryForTable() -> PFQuery {
let query:PFQuery = PFQuery(className:self.parseClassName!)
query.whereKey("client", equalTo: currentUser!)
query.whereKey("status", equalTo: "Open")
query.whereKey("expires", greaterThan: NSDate())
query.includeKey("group")
query.includeKey("category")
query.includeKey("client")
query.orderByAscending("expires")
if(objects?.count == 0)
{
query.cachePolicy = PFCachePolicy.CacheThenNetwork
}
return query
}
When my PFQueryTableViewController calls it's cellForRowAtIndexPath function, I have code to get the 'name' column of the category object brought in via includeKey
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
...
if let category = task["category"] as? PFObject {
cell?.categoryLabel.text = String(category["name"])
}
...
}
Running this retrieval of the category's 'name' value results in the following error and crash in Xcode:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Key "name" has no data. Call fetchIfNeeded before getting its value.'
This same error results when I attempt to access any additional columns of my pointer reference objects.
When I print(category) I appear to get a valid (but empty) object in my log, with no additional columns, like 'name':
<Category: 0x13c6ed870, objectId: mEpn6TH6Tc, localId: (null)> {
}
I have successfully tested calling the suggested fetch query to retrieve the missing pointer data for each pointer column, but (IMHO) the additional fetch defeats the purpose of the includeKey query option to limit API requests.
One thought I had was that a PFQuery may only allow one includeKey call. But, the research that I've done through both Parse's own iOS documentation and various developer posts do not indicate any limitation of max number of includeKeys a query can have.
Am I doing something unsupported by Parse or am I just syntactically not retrieving each pointers' object data the proper way?
I'm running the latest ParseUI as of this posting (1.1.6) and Parse (1.9.0) with Xcode 7.0.1
Thank you in advance for reading my post! I am only a couple months into learning iOS development, so this is both interesting and frustrating at the same time!
cell.category.text = object.objectForKey("category")!.objectForKey("name") as! String
also, use the other "version" of cellForRowAtIndexPath, the one for PFQueryTableViewControllers:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject!) -> PFTableViewCell? {
//4
let cell = tableView.dequeueReusableCellWithIdentifier("yourCellIdentifier", forIndexPath: indexPath) as! yourCell
return cell
}
this allows you to use the above syntax that I answered with.

what is #params in Iron:router

with meteor's IronRouter, I'm trying to use the this.params object elsewhere, but confused as to what it is. It seems to be a zero length array, that is actually an object with named methods after the path components.
# coffee
#route 'magnets',
path: '/magnets/lesson/:lessonCname'
data: ->
if #ready()
debugger;
console.log("route.params", #params)
with this code, in the debug console I will get:
this.params
[]
this.params.lessonCname
"despite-magnets-01"
typeof(this.params)
"object"
this.params.length
0
this.ready()
but in passing the params object to a server method, the methods (ie "lessonCname") disappear.
If my understanding is correct, then the near-term question is what is the best way to retrieve/convert these methods to {property:value} so they can be serialized and passed to server calls?
There are two easy ways of solving your problem, you can either set a global variable from within the data scope (but this is considered bad practice, at least IMO) or you can use the "data" function, which returns the data context for the current template:
data: ->
window._globalscopedata = #params.whatever #setting global variable
return someCollection.findOne #returns data context
_id: #params.whatever
when proccessing this route I will have the whatever param available in _globalscoredata and my document available in the template context.
Take a look at the source code for retrieving the parameters from a path. params is an array, but may have named properties. To iterate over everything, you can use the for in loop:
for(var x in myArray){
// Do something.
}
In this way, you can copy over everything to a new object (there may be a simpler way to create a copy).
The params property attached to a RouteController is an object with the following properties :
hash : the value of the URL hash.
query : an object consisting of key/value pairs representing the query string.
a list of URL fragments with their name and actual value.
Let's take an example, for this route definition :
// using iron:router#1.0.0-pre2 new route definition
Router.route("/posts/:slug");
And this URL typed in the browser address bar : /posts/first-post#comments?lang=en
We can use the console to find out precisely what params will actually contain :
> Router.current().params
Which will display this result :
Object {
hash: "comments",
slug: "first-post",
query: {
lang: "en"
}
}
Here slug is already a property of the params object whose value is "first-post", this is not a method.
If you want to extract from params these URL fragments as an object of key/value pairs, you can use underscore omit :
// getting rid of the hash and the query string
var parameters=_.omit(this.params,["hash","query"]);

Resources