updating model with parameter in elm 0.18 - list

New to elm. Using elm 0.18.
This is a very simple SPA with 12 buttons (each with a musical note value). You click the button, and it displays the note you clicked.
I'd like to do this by assigning a function Put to a button via onClick, then passing it a string parameter note that gets used to update the model.
Here is my code:
import Html exposing (div, beginnerProgram, text, button)
import Html.Events exposing (onClick)
import List exposing (..)
main =
beginnerProgram { model = model, update = update, view = view }
-- model
model =
{ key = "C" }
keys =
["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
-- update
type Action = Put
update msg model =
case msg note of
Put ->
{ model | key = note }
-- view
makeButton note =
button [ onClick Put note ] [text note]
view model =
div [] [
div [] [text (toString model.key)],
div [] (map makeButton keys)
]
I get this error:
-- NAMING ERROR -------------------------------------------------- musiccalc.elm
Cannot find variable `note`
19| case msg note of

Got it, you type the action, then evaluate first before going into onClick.
import Html exposing (div, beginnerProgram, text, button)
import Html.Events exposing (onClick)
import List exposing (..)
main =
beginnerProgram { model = model, update = update, view = view }
-- model
model =
{ key = "C" }
keys =
["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
-- update
type Action =
Put String
update msg model =
case msg of
Put note ->
{ model | key = note }
-- view
makeButton note =
button [ onClick (Put note) ] [text note]
view model =
div [] [
div [] [text (toString model.key)],
div [] (map makeButton keys)
]

Related

Filtering ArrayField by entire and exact array only?

I have a slug ArrayField on a model.
How can I filter or get by the entire exact array only?
I'm currently doing something like this:
search = f'["a", "b", "c"]'
list = search[2:-2].split("', '")
dict = {}
for n, item in enumerate(list):
dict[f"slug__{n}"] = item
obj = queryset.filter(**dict)
However, this returns any object where the slug begins with "a", "b", and "c".
E.g.
["a", "b", "c"]
["a", "b", "c", "d"]
["a", "b", "c", "d", "e"]
["a", "b", "c", "123"]
How do I do a filter or get so that only the entire and exact slug match returns? I.e. obj only returns objects with a slug of ["a", "b", "c"]
To filter an ArrayField by an exact match you can just pass the list to match against to a filter
queryset = queryset.filter(slug=["a", "b", "c"])

How to append to a list in Terraform?

I have some code in the general form:
variable "foo" {
type = "list"
default = [ 1,2,3 ]
}
resource "bar_type" "bar" {
bar_field = "${var.foo}"
}
I want to append an addition value to bar_field without modifying foo. How can I do this? I don't see any sort of contacting or appending functions in their docs.
This is 0.11.x Terraform
You can use the concat function for this. Expanding upon the example in your question:
variable "foo" {
type = "list"
default = [ 1,2,3 ]
}
# assume a value of 4 of type number is the additional value to be appended
resource "bar_type" "bar" {
bar_field = "${concat(var.foo, [4])}"
}
which appends to the value assigned to bar_field while ensuring var.foo remains unchanged.
Adding new item to the list if not present:
locals {
oldlist = ["a", "b", "c"]
newitem = "d"
newlist = (contains(local.oldlist, local.newitem) == false ? concat(local.oldlist, [local.newitem]) : local.oldlist)
}
output "newlist" {
value = local.newlist
}
var1 = ["string1","string2"]
var2 = "string3"
var3 = concat(var1, formatlist(var2))

How do I insert or create data with Django ORM programmatically? Or how do I specific Model field name with a string?

If I have:
class Tag(models.Model):
number = models.IntegerField()
config = {
"data": 1,
"field": "number"
}
How do I do the following?
record = Tag(config["field"]=config["data"])
record.save()
You can unpack dict to arguments using this syntax **. For example:
config = {
"number": 1
}
record = Tag(**config)
record.save()
This will create new tag instance with number=1 value.

Facebook Open Graph - Can "og.likes" action be assigned with "product" type?

The following iOS code ("object" type with "og.likes" action) works just fine:
let properties = [
"og:type": "object",
"og:title": "Test Product",
"og:description": "Product description"
]
let object = FBSDKShareOpenGraphObject(properties: properties)
let action = FBSDKShareOpenGraphAction()
action.actionType = "og.likes"
action.setObject(object, forKey: "object")
let content = FBSDKShareOpenGraphContent()
content.action = action
content.previewPropertyName = "object"
FBSDKShareDialog.show(from: self, with: content, delegate: nil)
However, I prefer using "product" type rather than the generic "object" type. The following code is the same as the above one only replacing "object" with "product" (so this time trying to post a story about "product" type with "og.likes" action)
let properties = [
"og:type": "product",
"og:title": "Test Product",
"og:description": "Product description"
]
let object = FBSDKShareOpenGraphObject(properties: properties)
let action = FBSDKShareOpenGraphAction()
action.actionType = "og.likes"
action.setObject(object, forKey: "product")
let content = FBSDKShareOpenGraphContent()
content.action = action
content.previewPropertyName = "product"
FBSDKShareDialog.show(from: self, with: content, delegate: nil)
This code generated the following error:
Action Requires At Least One Reference: The action you’re trying to
publish is invalid because it does not specify any reference objects.
At least one of the following properties must be specified: object.
Any idea why?

How to set an Array<Object> inside a Dictionary<String, AnyObject> - Swift3

I'm new in swift. I'm trying to add an Array to a specific key in my Dictionary.
I have the following code:
var myArray : Array<Links> = []
var myDict : Dictionary<String, AnyObject> = [:]
myDict["links"] = myArray as AnyObject? // I need help in this row, It does not work.
This is the Json structure I have in myDict and I'm trying to set:
id : "blabla"
links: [
0: {key1: "a", key2: "b", name: "c", link: "d"}
1: {key1: "e", key2: "f", name: "j", link: "h"}
]
Please, consider I already have all the rest working properly. My only problem is how to add my array in the dictionary as commented in the code above.
My JSON structure:
I hope I could make myself clear enough.
Thank you.
First of all don't cast types up and don't annotate types unless the compiler complains.
Second of all a JSON dictionary is [String:Any] in Swift 3.
Further the recommended syntax to create an empty collection object is
var myDict = Dictionary<String, Any>()
Assuming your array – actually a dictionary – is
let myArray = [
0: ["key1": "a", "key2": "b", "name": "c", "link": "d"],
1: ["key1": "e", "key2": "f", "name": "j", "link": "h"]
]
just assign it:
myDict["links"] = myArray
Even if there is a struct
struct Link {
var key1, key2, name, link : String
}
and the array dictionary is
let linkDictionary = [
0: Link(key1:"a", key2: "b", name: "c", link: "d"),
1: Link(key1:"e", key2: "f", name: "g", link: "h")]
you can assign it if the value type is Any
myDict["links"] = linkDictionary
Assuming, for a second, that links really was an array, it would be:
var dictionary: [String: Any] = [
"id": "blabla",
"links": [
["key1": "a", "key2": "b", "name": "c", "link": "d"],
["key1": "e", "key2": "f", "name": "j", "link": "h"]
]
]
// retrieve links, or initialize it if not found
var links = dictionary["links"] as? [[String: String]] ?? [[String: String]]()
// add your new link to local dictionary
links.append(["key1": "k", "key2": "l", "name": "m", "link": "n"])
// update original structure
dictionary["links"] = links
Personally, though, when I see a repeating dictionary structure like your links, this screams for a real model for these objects. For example:
struct Foo {
let id: String
var links: [Link]?
}
struct Link {
let key1: String
let key2: String
let name: String
let link: String
}
var foo = Foo(id: "blabla", links: [
Link(key1: "a", key2: "b", name: "c", link: "d"),
Link(key1: "e", key2: "f", name: "j", link: "h")
])
foo.links?.append(Link(key1: "k", key2: "l", name: "m", link: "n"))
Now, in this latter example, I assumed that links was really an array, not a dictionary, but that's not really my point here. My key observation is that code is more readable and robust if you use proper custom types rather than just arrays and dictionaries.
And if you need to send and receive these model objects to some web service, you then map this model object to and from JSON. But use custom types for your actual model.
If you want to make the above types easily converted to and from JSON, you can use one of the object mapping libraries out there, so you can do something yourself, e.g.:
protocol Jsonable {
var jsonObject: Any { get }
init?(jsonObject: Any)
}
extension Foo: Jsonable {
var jsonObject: Any {
return [
"id": id,
"links": links?.map { $0.jsonObject } ?? [Any]()
]
}
init?(jsonObject: Any) {
guard let dictionary = jsonObject as? [String: Any],
let id = dictionary["id"] as? String else { return nil }
var links: [Link]?
if let linksDictionary = dictionary["links"] as? [Any] {
links = linksDictionary.map { Link(jsonObject: $0)! }
}
self.init(id: id, links: links)
}
}
extension Link: Jsonable {
var jsonObject: Any { return [ "key1": key1, "key2": key2, "name": name, "link": link ] }
init?(jsonObject: Any) {
guard let dictionary = jsonObject as? [String: Any],
let key1 = dictionary["key1"] as? String,
let key2 = dictionary["key2"] as? String,
let name = dictionary["name"] as? String,
let link = dictionary["link"] as? String else {
return nil
}
self.init(key1: key1, key2: key2, name: name, link: link)
}
}
Then you can do stuff like:
let object = try JSONSerialization.jsonObject(with: data)
var foo = Foo(jsonObject: object)!
Or:
foo.links?.append(Link(key1: "j", key2: "k", name: "l", link: "m"))
let data = try! JSONSerialization.data(withJSONObject: foo.jsonObject)
This was the solution:
var arrLinks : Array<Dictionary<String, Any>> = []
for link in myArray {
var dict : Dictionary<String, Any> = [:]
dict["key1"] = link.name
dict["key2"] = link.ghostBefore
dict["key3"] = link.ghostAfter
arrLinks.append(dict)
}
myDict["links"] = arrLinks as AnyObject