Clean alternative to Binding's now-deprecated Collection conformance? - collections

As of Xcode 11 beta 6…
The Binding structure’s conditional conformance to the Collection protocol is removed.
Going with Apple's recommendation (at that link) of creating an IndexedCollection type, we can avoid boilerplate for List and ForEach like this:
public extension ForEach where Content: View {
init<Base: RandomAccessCollection>(
_ base: Base,
#ViewBuilder content: #escaping (Data.Element) -> Content
)
where
Data == IndexedCollection<Base>,
Base.Element: Identifiable,
ID == Base.Element.ID
{
self.init(IndexedCollection(base: base), id: \.element.id, content: content)
}
}
That takes us from their example,
List(landmarks.indexed(), id: \.1.id) { index, landmark in
Toggle(landmark.name, isOn: self.$landmarks[index].isFavorite)
}
to this:
List(landmarks) { index, landmark in
Toggle(landmark.name, isOn: self.$landmarks[index].isFavorite)
}
But is it possible to write another extension initializer, to allow for avoiding having to use the index and subscript (self.$landmarks[index])?
I've tried making use of dynamicMemberLookup, but if that's the solution, I didn't get it right yet.

Related

WpContentNode[] is not assignable to type WpPage[] error in Gatsby+WordPress+TypeScript project

This error occurs within a Gatsby + WordPress + TypeScript project component when pulling WordPress page data along with its child page data via GraphQL.
Type 'WpContentNode[]' is not assignable to type 'WpPage[]'.
On line:
const pages: WpPage[] = page?.wpChildren?.nodes;
The data is being fetched from a GraphQL query in the page component:
query {
allWpPage(filter: { databaseId: { eq: 383 } }) {
nodes {
...standardPageFields
wpChildren {
nodes {
... on WpPage {
id
uri
title
...etc
}
}
}
}
}
}
This part of the query appears to not be meshing well with the generated TypeScript interfaces:
wpChildren {
nodes {
... on WpPage {
id
...
}
}
}
wpChildren.nodes is typed as WpContentNode[] even though it's pulling from ... on WpPage. I'd think it would be typed as WpPage[] as a result of the ... on WpPage within the query.
These type definitions are all being generated with graphql-codegen. The majority are working fine. Only running into this one issue with matching the appropriate type to a ... on WpPage query.
How can I type wpChildren.nodes as WpPage[]? They are child pages of the parent node.
Note: We're avoiding the use of any to make this error go away, so that is not a viable solution for me. We're aiming to adhere to strict typing.
Thanks in advance for any insight.

App crashes when I attempt to have a dynamic value in spinner

I have the following code and was wondering why it crashes the app, I was hoping you could help me figure out what was going on.
The code below is not exact aside from the spinner code.
The idea is to have the spinner racePicker's array populated by FireStore document IDs, as shown below:
val db = FirebaseFirestore.getInstance()
val raceArray = ArrayList()
raceArray.add("Select race...")
db.collection("races").get().addOnSuccessListener {
DocumentSnapshot ->
for (document in DocumentSnapshot) {
raceArray.add(document.id)
Log.e("info", "raceArray contains values $raceArray")
}
This is a rough approximation. I may have set it .toString() or maybe used .addAll vs .add in the raceArray statement.
(I honestly don't remember exactly if this is how I coded it, but it's close enough to give an idea, I'm typing from memory at the moment).
My intention was to use it like so:
racPicker.onSelectedItemListener = object :
OnItemSelectedListener {
override fun onNothingSelected() {
}
override fun onItemSelected(parent: AdapterView<*>?, view:
View?, position: Int, id: Long) {
val selection = parent?.getItemAtPosition(position).toString()
when (selection) {
"$selection" -> raceArray.remove("Select race...").also{
statAllocator(selection) }
}
}
}
For some reason it crashes, but if I assign a literal such as "race name" -> fun, "2nd race name" -> fun, etc it works.
Would it be better to use
if (selectedItem.equals("$selection") {
// do stufd
}
instead? Or is it absolutely necessary to call each and every when case/statement as a literal string? I essentially am looking for a way to have the spinner's selected item (which is an array of document names generated from FireStore database) then "check for itself" and trigger the other functions.

NGRX: Composing state when we have to represent data from two lists

Practical example: Consider an expand/collapse list. Each item expands another list.
export interface MainDomainList {
id: number
name: string;
}
export interface SubDomainList {
id: number
name: string;
}
export interface AppState {
mainDomainList: MainDomainList[];
subDomainList: SubDomainList[];
}
On the UI the list should be represented like this:
MainDomainList[1]
SubDomainList[] (entire list)
MainDomainList[2]
Another SubDomainList[] (entire list)
etc..
When the user clicks on the MainDomain[n] there is a call to the backend which returns a list of SubDomain[]. There are no connections between the two of them.
It seems that the most complicated part is that the SubDomains are being loaded one by one on click not all at once, and multiple MainDomains can be open at the same time like in the example above. Also, it should be possible to easily perform CRUD operations on the subDomainList entities.
I tried using a selector which selects an item from the state by id but every time the state is overridden.
My initial idea was to create a separate state in which after the SubDomainList[] is loaded successfully, then I could add the loaded SubDomainList[] by dispatching an 'ADD' action thus adding the entities and the id of the clicked MainDomainList in the newList state as the user clicks on through the list obtaining something like this:
exportt interface AppState {
mainDomainList: MainDomainList[];
subDomainList: SubDomainList[];
newList: NewList[];
}
{
mainDomainList : {
entities: {
md1: {
id: 'md1',
name: '1'
},
md2: {
id: 'md2',
name: '2'
}
}
},
subDomainList : {
entities : {
sd1 : {
id : 'sd1',
name: 'name1'
},
sd2 : {
id : 'sd2',
name: 'name2'
}
},
newList : {
entities : {
md1 : {
id : 'md1',
subDomainList: [{}, {}]
},
md2 : {
id : 'md2',
subDomainList: [{}, {}]
}
}
}
}
Then somehow i would get all the newList entities and match them in the UI with the id of the MainDomainList[n].id
Is my approach correct or is there any other better or less complicated solution for this issue?
I'm fairly new to the subject but I had a lot of headaches trying to figure out how to implement this with ngrx/Entity and failed so far, although it should be a pretty common case. Any help would be much appreciated.
You can write selectors with argument by passing of main domain list
ref: ngrx parameter to select function
and https://blog.angularindepth.com/ngrx-parameterized-selector-e3f610529f8

GTM Macro to set GUA_ID based on domain/hostname/url

We have several websites. During set-up of GTM I was wondering if I needed to set-up 1 GTM-container for alle websites (and make it variable) or set-up 1 container per website. The latter seemed like a lot of manual config.
However, to achieve a more dynamic approach I was wondering if I can set the GUA ID depending on a url/hostname regex lookup table.
Making it more difficult: We have both different domains as same domains with subfolders for languages so the lookup table has to support both.
My question: will a macro lookup like this work or does a better method exist to achieve the same result?
See the image below as example
Lookup table macro doesn't support regular expressions. You should use transitional custom JS-macro or tag in which you check your regexp's. Then you may push it to datalayer or return in macro used as a key in your lookup table
For example
v1 - js tag
<script>
categories=[
/\/moscow\/.*kupit-kvartiru\/kvartiri-studii\//,
/\/moscow\/.*kupit-kvartiru\/odnokomnatnie-kvartiri\//,
/\/moscow\/.*kupit-kvartiru\/dvuhkomnatnie-kvartiri\//,
/\/moscow\/.*kupit-kvartiru\/trehkomnatnie-kvartiri\//,
/\/moscow\/.*kupit-kvartiru\/chetyrehkomnatnie-kvartiri\//,
/\/moscow\/.*kupit-kvartiru\/bolshie-kvartiri\//
];
for (i in categories) {
if (RegExp(categories[i]).test({{url}})) {
category_type_for_retargeting=categories[i].toString().slice(1,-1);
dataLayer.push({
'event' : 'regex_event',
'category' : category_type_for_retargeting
});
}
}
</script>
v2 - js macro for lookup table
function() {
categories=[
/\/moscow\/.*kupit-kvartiru\/kvartiri-studii\//,
/\/moscow\/.*kupit-kvartiru\/odnokomnatnie-kvartiri\//,
/\/moscow\/.*kupit-kvartiru\/dvuhkomnatnie-kvartiri\//,
/\/moscow\/.*kupit-kvartiru\/trehkomnatnie-kvartiri\//,
/\/moscow\/.*kupit-kvartiru\/chetyrehkomnatnie-kvartiri\//,
/\/moscow\/.*kupit-kvartiru\/bolshie-kvartiri\//
];
for (i in categories) {
if (RegExp(categories[i]).test({{url}})) {
category_type_for_retargeting=categories[i].toString().slice(1,-1);
return category_type_for_retargeting;
}
}
return -1; //default value
}
v3 - js macro as UA id
function() {
categories={
"UA-1234-1" : /\/moscow\/.*kupit-kvartiru\/kvartiri-studii\//,
"UA-1234-2" : /\/moscow\/.*kupit-kvartiru\/odnokomnatnie-kvartiri\//,
"UA-1234-3" : /\/moscow\/.*kupit-kvartiru\/dvuhkomnatnie-kvartiri\//,
"UA-1234-4" : /\/moscow\/.*kupit-kvartiru\/trehkomnatnie-kvartiri\//,
"UA-1234-5" : /\/moscow\/.*kupit-kvartiru\/chetyrehkomnatnie-kvartiri\//,
"UA-1234-6" : /\/moscow\/.*kupit-kvartiru\/bolshie-kvartiri\//
};
for (i in categories) {
if (RegExp(categories[i]).test({{url}})) return i;
}
}

BlackBerry Cascades prints {Error} when I use Share action

I'm developing an app for black-berry, and one of its functionalies is to share a 'note' to other apps, so its text can be used (on an e-mail, for example), but it keeps printing "{Error}" where it should print the message.
I used the following:
actions: [
InvokeActionItem {
ActionBar.placement: ActionBarPlacement.OnBar
id: shareNoteActionItem
query {
mimeType: "text/plain"
data: Qt._filesController.stoba(noteContent)
invokeActionId: "bb.action.SHARE"
}
}
]
Where Qt._filesController is an object of FilesController class, and stoba() is the following function:
QByteArray FilesController::stoba(QString str) {
return str.toLocal8Bit();
}
And noteContent is QString. I've tried other conversions, but none seems to work. What should i do?

Resources