问:
How to create a radio button group with custom PickerStyle?
PickerStyle offers WheelPickerStyle, SegmentedPickerStyle and more. I want to customise it create a radio buttons that only one should be selected at a time.

I am Android Developer and very new to swift. I am using SwiftUI for my UI needs.

I looked into the documentation and there is a PickerStyle protocol but I am not able to implement it and didn't find any tutorial. I have following code for this:

```<code>struct RadioPickerStyle: PickerStyle {

    static func _makeView<SelectionValue>(value: _GraphValue<_PickerValue<RadioPickerStyle, SelectionValue>>, inputs: _ViewInputs) -> _ViewOutputs where SelectionValue : Hashable {
//        Text("\(value)")
    }

    static func _makeViewList<SelectionValue>(value: _GraphValue<_PickerValue<RadioPickerStyle, SelectionValue>>, inputs: _ViewListInputs) -> _ViewListOutputs where SelectionValue : Hashable {
//        List(inputs) {
//            ForEach
//        }
    }

</code>```

I want to use it in the following code:

```<code>...
    @State var gender: Int = 0
    let genderOptions: [String] = ["Male", "Female", "Other"]
...
                    Picker("Gender", selection: $gender) {
                        ForEach(0 ..< genderOptions.count) { option in
                            Text(self.genderOptions[option])
                                .tag(self.gender)
                        }
                    }
                    .pickerStyle(RadioPickerStyle())
...
</code>```

Does anyone can give me idea of what is _ViewInputs, _ViewOutputs ,_ViewListInputs and _ViewListOutputs?

答:
using this code you get tag value in selected variable.</p>

```<code>@State private var selected : Int = 0

Picker("Gender:", selection: $selected){
    Text("Male").tag(0)
    Text("Female").tag(1)
    Text("Male").tag(0)
}.pickerStyle(RadioPickerStyle())

Text("\(selected)")
</code>```

Body:
PickerStyle offers WheelPickerStyle, SegmentedPickerStyle and more. I want to customise it create a radio buttons that only one should be selected at a time.

I am Android Developer and very new to swift. I am using SwiftUI for my UI needs.

I looked into the documentation and there is a PickerStyle protocol but I am not able to implement it and didn't find any tutorial. I have following code for this:

struct RadioPickerStyle: PickerStyle {

    static func _makeView<SelectionValue>(value: _GraphValue<_PickerValue<RadioPickerStyle, SelectionValue>>, inputs: _ViewInputs) -> _ViewOutputs where SelectionValue : Hashable {
//        Text("\(value)")
    }

    static func _makeViewList<SelectionValue>(value: _GraphValue<_PickerValue<RadioPickerStyle, SelectionValue>>, inputs: _ViewListInputs) -> _ViewListOutputs where SelectionValue : Hashable {
//        List(inputs) {
//            ForEach
//        }
    }

I want to use it in the following code:

...
    @State var gender: Int = 0
    let genderOptions: [String] = ["Male", "Female", "Other"]
...
                    Picker("Gender", selection: $gender) {
                        ForEach(0 ..< genderOptions.count) { option in
                            Text(self.genderOptions[option])
                                .tag(self.gender)
                        }
                    }
                    .pickerStyle(RadioPickerStyle())
...

Does anyone can give me idea of what is _ViewInputs, _ViewOutputs ,_ViewListInputs and _ViewListOutputs?

Body:
using this code you get tag value in selected variable.

@State private var selected : Int = 0

Picker("Gender:", selection: $selected){
    Text("Male").tag(0)
    Text("Female").tag(1)
    Text("Male").tag(0)
}.pickerStyle(RadioPickerStyle())

Text("\(selected)")


来源: stackexchange

问:
Display data from json file in angular
I Have the following Json file and i want to output data as categories(pizza, pasta) and then sub-categories(pizza margherita, pizza prosciutto) and same for pasta and for each to have choices, exactly as the structure in the file.

This is json file which i wanted to output it. I use ngfor to loop through the array but how to display from first option, both categories?

```<code>    [
    {
    "name" : "Pizza",
    "category": [
        {
            "name": "Pizza Marquerita",
            "choices": [
                {
                    "name": "Crust",
                    "addons" : [
                        {
                            "name": "Crispy"
                        },
                        {
                            "name": "Fluffy"
                        }
                    ]
                },
                {
                    "name": "Extra Toppings",
                    "addons" : [
                        {
                            "name": "Olives"
                        },
                        {
                            "name": "Mushrooms"
                        }
                    ]
                }
            ]
        },
        {
            "name": "Pizza Prosciutto",
            "choices": [
                {
                    "name": "Crust",
                    "addons" : [
                        {
                            "name": "Crispy"
                        },
                        {
                            "name": "Fluffy"
                        }
                    ]
                },
                {
                    "name": "Extra Toppings",
                    "addons" : [
                        {
                            "name": "Olives"
                        },
                        {
                            "name": "Mushrooms"
                        }
                    ]
                }
            ]
        }
    ],
    "choices": [
        {
            "name": "Crust",
            "addons" : [
                {
                    "name": "Crispy"
                },
                {
                    "name": "Fluffy"
                }
            ]
        },
        {
            "name": "Extra Toppings",
            "addons" : [
                {
                    "name": "Olives"
                },
                {
                    "name": "Mushrooms"
                }
            ]
        }
    ]},
    {
    "name" : "Pasta",
    "category": [
        {
            "name": "Spaghetti Bolognese",
            "choices": [
                {
                    "name": "Pasta Type",
                    "addons" : [
                        {
                            "name": "Spaghetti"
                        },
                        {
                            "name": "Tagliatelle"
                        }
                    ]
                },
                {
                    "name": "Extra Toppings",
                    "addons" : [
                        {
                            "name": "extra sea food"
                        },
                        {
                            "name": "truffle"
                        }
                    ]
                }
            ]
        },
        {
            "name": "Spaghetti Frutti di Mare",
            "choices": [
                {
                    "name": "Pasta Type",
                    "addons" : [
                        {
                            "name": "Spaghetti"
                        },
                        {
                            "name": "Tagliatelle"
                        }
                    ]
                },
                {
                    "name": "Extra Toppings",
                    "addons" : [
                        {
                            "name": "extra sea food"
                        },
                        {
                            "name": "truffle"
                        }
                    ]
                }
            ]
        }
    ],
    "choices": [
        {
            "name": "Pasta Type",
            "addons" : [
                {
                    "name": "Spaghetti"
                },
                {
                    "name": "Tagliatelle"
                }
            ]
        },
        {
            "name": "Extra Toppings",
            "addons" : [
                {
                    "name": "extra sea food"
                },
                {
                    "name": "truffle"
                }
            ]
        }
    ]}

]
</code>```

In .ts file i import the file
import data from '../../assets/data.json'; and then declare it as menus: any = data;

in html i want to output data as a card just something simple. If i use it like that. it displays pizza margherita and spaghetti bolognese under pizza

```<code>    <div class="card" style="width: 18rem;">
  <div class="card-body">
    <h5 class="card-title">Restaurant Name</h5>
  </div>
  <div class="card-header">Pizza</div>
  <ul class="list-group list-group-flush">
  <li class="list-group-item" *ngFor="let menu of menus">{{menu.category[0].name}}</li>
  </ul>
  <div class="card-header">Pasta</div>
  <ul class="list-group list-group-flush">
    <li class="list-group-item">test</li>
  </ul>
</div>
</code>```

答:
You can also use the below code. I think it will be a remove redundant code.

```<code><div class="card" style="width: 18rem;">
    <div class="card-body">
        <h5 class="card-title">Restaurant Name</h5>
    </div>
    <span *ngFor="let data of menus">
        <div class="card-header">{{data.name}}</div>
        <ul class="list-group list-group-flush">
        <li class="list-group-item" *ngFor="let menu of data.category">{{menu.name}}</li>
        </ul>
    </span>
</div>
</code>```

and your data is here

```<code>menus: any = [
    {
    name : "Pizza",
    category: [
        {
            name: "Pizza Marquerita",
            choices: [
                {
                    name: "Crust",
                    addons : [
                        {
                            name: "Crispy"
                        },
                        {
                            name: "Fluffy"
                        }
                    ]
                },
                {
                    name: "Extra Toppings",
                    addons : [
                        {
                            name: "Olives"
                        },
                        {
                            name: "Mushrooms"
                        }
                    ]
                }
            ]
        },
        {
            name: "Pizza Prosciutto",
            choices: [
                {
                    name: "Crust",
                    addons : [
                        {
                            name: "Crispy"
                        },
                        {
                            name: "Fluffy"
                        }
                    ]
                },
                {
                    name: "Extra Toppings",
                    addons : [
                        {
                            name: "Olives"
                        },
                        {
                            name: "Mushrooms"
                        }
                    ]
                }
            ]
        }
    ],
    choices: [
        {
            name: "Crust",
            addons : [
                {
                    name: "Crispy"
                },
                {
                    name: "Fluffy"
                }
            ]
        },
        {
            name: "Extra Toppings",
            addons : [
                {
                    name: "Olives"
                },
                {
                    name: "Mushrooms"
                }
            ]
        }
    ]},
    {
    name : "Pasta",
    category: [
        {
            name: "Spaghetti Bolognese",
            choices: [
                {
                    name: "Pasta Type",
                    addons : [
                        {
                            "name": "Spaghetti"
                        },
                        {
                            "name": "Tagliatelle"
                        }
                    ]
                },
                {
                    name: "Extra Toppings",
                    addons : [
                        {
                            name: "extra sea food"
                        },
                        {
                            name: "truffle"
                        }
                    ]
                }
            ]
        },
        {
            name: "Spaghetti Frutti di Mare",
            choices: [
                {
                    name: "Pasta Type",
                    addons : [
                        {
                            name: "Spaghetti"
                        },
                        {
                            name: "Tagliatelle"
                        }
                    ]
                },
                {
                    name: "Extra Toppings",
                    addons : [
                        {
                            name: "extra sea food"
                        },
                        {
                            name: "truffle"
                        }
                    ]
                }
            ]
        }
    ],
    choices: [
        {
            name: "Pasta Type",
            addons : [
                {
                    name: "Spaghetti"
                },
                {
                    name: "Tagliatelle"
                }
            ]
        },
        {
            name: "Extra Toppings",
            addons : [
                {
                    name: "extra sea food"
                },
                {
                    name: "truffle"
                }
            ]
        }
    ]}
]
</code>```

ContentLicense: CC BY-SA 4.0

Title: Display data from json file in angular

Body:
I Have the following Json file and i want to output data as categories(pizza, pasta) and then sub-categories(pizza margherita, pizza prosciutto) and same for pasta and for each to have choices, exactly as the structure in the file.

This is json file which i wanted to output it. I use ngfor to loop through the array but how to display from first option, both categories?

    [
    {
    "name" : "Pizza",
    "category": [
        {
            "name": "Pizza Marquerita",
            "choices": [
                {
                    "name": "Crust",
                    "addons" : [
                        {
                            "name": "Crispy"
                        },
                        {
                            "name": "Fluffy"
                        }
                    ]
                },
                {
                    "name": "Extra Toppings",
                    "addons" : [
                        {
                            "name": "Olives"
                        },
                        {
                            "name": "Mushrooms"
                        }
                    ]
                }
            ]
        },
        {
            "name": "Pizza Prosciutto",
            "choices": [
                {
                    "name": "Crust",
                    "addons" : [
                        {
                            "name": "Crispy"
                        },
                        {
                            "name": "Fluffy"
                        }
                    ]
                },
                {
                    "name": "Extra Toppings",
                    "addons" : [
                        {
                            "name": "Olives"
                        },
                        {
                            "name": "Mushrooms"
                        }
                    ]
                }
            ]
        }
    ],
    "choices": [
        {
            "name": "Crust",
            "addons" : [
                {
                    "name": "Crispy"
                },
                {
                    "name": "Fluffy"
                }
            ]
        },
        {
            "name": "Extra Toppings",
            "addons" : [
                {
                    "name": "Olives"
                },
                {
                    "name": "Mushrooms"
                }
            ]
        }
    ]},
    {
    "name" : "Pasta",
    "category": [
        {
            "name": "Spaghetti Bolognese",
            "choices": [
                {
                    "name": "Pasta Type",
                    "addons" : [
                        {
                            "name": "Spaghetti"
                        },
                        {
                            "name": "Tagliatelle"
                        }
                    ]
                },
                {
                    "name": "Extra Toppings",
                    "addons" : [
                        {
                            "name": "extra sea food"
                        },
                        {
                            "name": "truffle"
                        }
                    ]
                }
            ]
        },
        {
            "name": "Spaghetti Frutti di Mare",
            "choices": [
                {
                    "name": "Pasta Type",
                    "addons" : [
                        {
                            "name": "Spaghetti"
                        },
                        {
                            "name": "Tagliatelle"
                        }
                    ]
                },
                {
                    "name": "Extra Toppings",
                    "addons" : [
                        {
                            "name": "extra sea food"
                        },
                        {
                            "name": "truffle"
                        }
                    ]
                }
            ]
        }
    ],
    "choices": [
        {
            "name": "Pasta Type",
            "addons" : [
                {
                    "name": "Spaghetti"
                },
                {
                    "name": "Tagliatelle"
                }
            ]
        },
        {
            "name": "Extra Toppings",
            "addons" : [
                {
                    "name": "extra sea food"
                },
                {
                    "name": "truffle"
                }
            ]
        }
    ]}

]

In .ts file i import the file
import data from '../../assets/data.json'; and then declare it as menus: any = data;

in html i want to output data as a card just something simple. If i use it like that. it displays pizza margherita and spaghetti bolognese under pizza

Restaurant Name

Pizza

{{menu.category[0].name}}

Pasta

test

Body:
You can also use the below code. I think it will be a remove redundant code.

<div class="card" style="width: 18rem;">
    <div class="card-body">
        <h5 class="card-title">Restaurant Name</h5>
    </div>
    <span *ngFor="let data of menus">
        <div class="card-header">{{data.name}}</div>
        <ul class="list-group list-group-flush">
        <li class="list-group-item" *ngFor="let menu of data.category">{{menu.name}}</li>
        </ul>
    </span>
</div>

and your data is here

menus: any = [
    {
    name : "Pizza",
    category: [
        {
            name: "Pizza Marquerita",
            choices: [
                {
                    name: "Crust",
                    addons : [
                        {
                            name: "Crispy"
                        },
                        {
                            name: "Fluffy"
                        }
                    ]
                },
                {
                    name: "Extra Toppings",
                    addons : [
                        {
                            name: "Olives"
                        },
                        {
                            name: "Mushrooms"
                        }
                    ]
                }
            ]
        },
        {
            name: "Pizza Prosciutto",
            choices: [
                {
                    name: "Crust",
                    addons : [
                        {
                            name: "Crispy"
                        },
                        {
                            name: "Fluffy"
                        }
                    ]
                },
                {
                    name: "Extra Toppings",
                    addons : [
                        {
                            name: "Olives"
                        },
                        {
                            name: "Mushrooms"
                        }
                    ]
                }
            ]
        }
    ],
    choices: [
        {
            name: "Crust",
            addons : [
                {
                    name: "Crispy"
                },
                {
                    name: "Fluffy"
                }
            ]
        },
        {
            name: "Extra Toppings",
            addons : [
                {
                    name: "Olives"
                },
                {
                    name: "Mushrooms"
                }
            ]
        }
    ]},
    {
    name : "Pasta",
    category: [
        {
            name: "Spaghetti Bolognese",
            choices: [
                {
                    name: "Pasta Type",
                    addons : [
                        {
                            "name": "Spaghetti"
                        },
                        {
                            "name": "Tagliatelle"
                        }
                    ]
                },
                {
                    name: "Extra Toppings",
                    addons : [
                        {
                            name: "extra sea food"
                        },
                        {
                            name: "truffle"
                        }
                    ]
                }
            ]
        },
        {
            name: "Spaghetti Frutti di Mare",
            choices: [
                {
                    name: "Pasta Type",
                    addons : [
                        {
                            name: "Spaghetti"
                        },
                        {
                            name: "Tagliatelle"
                        }
                    ]
                },
                {
                    name: "Extra Toppings",
                    addons : [
                        {
                            name: "extra sea food"
                        },
                        {
                            name: "truffle"
                        }
                    ]
                }
            ]
        }
    ],
    choices: [
        {
            name: "Pasta Type",
            addons : [
                {
                    name: "Spaghetti"
                },
                {
                    name: "Tagliatelle"
                }
            ]
        },
        {
            name: "Extra Toppings",
            addons : [
                {
                    name: "extra sea food"
                },
                {
                    name: "truffle"
                }
            ]
        }
    ]}
]


问:
Order of cancellation of effects (useEffect) in React
when a component is unmounted, for some reason, the effect is canceled first for the parent component, and then for the child components... (we are talking about useEffect hooks)

It doesn't make sense...

What could be the problem?

The problem is that I have map routes in my child components.. And when routes are unmounted, they try to delete themselves in the map... and the map has already been removed, because the cancellation of the effect for the parent component is called earlier than for the child components (the child components learn about the parent through the context)

https://codesandbox.io/s/ocherednost-otmeny-effektov-g0z0r

See the browser console

I expect:
Child cancel useEffect
Parent cancel useEffect

答:
I'm guessing you might stumble upon a warning about updating unmounted components. You could use the following pattern to work around this:

```<code>useEffect(() => {

    let mounted = true;

    if(mounted){
        updateMyComponent();
    }

    return () => {
         mounted = false;
    }

}, [deps]);
</code>```

When the component unmounts, mounted will change to false and updateMyComponent will not run. Maybe this solves the issue that you have in your child components?

Body:
I'm guessing you might stumble upon a warning about updating unmounted components. You could use the following pattern to work around this:

useEffect(() => {

    let mounted = true;

    if(mounted){
        updateMyComponent();
    }

    return () => {
         mounted = false;
    }

}, [deps]);

When the component unmounts, mounted will change to false and updateMyComponent will not run. Maybe this solves the issue that you have in your child components?


问:
Merge two objects(optimizing)
I have n objects(with some nested structure). In the end, I'm expecting to get one merged object with all fields.

```<code>const result = {
  firstParam: {
    x: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    y: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    z: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    }
  },
  secondParam: {
    x: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    y: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    z: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    }
  },
  thirdParam: {
    x: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    y: {
      uuid1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    z: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    }
  }
}

const newObj1 = {
  firstParam: {
    x: {
      id2: ["somedata1", "somedata2"]
    },
    y: {
      id2: ["somedata1", "somedata2"]
    },
    z: {
      id2: ["somedata1", "somedata2"]
    }
  },
  secondParam: {
    x: {
      id2: ["somedata1", "somedata2"]
    },
    y: {
      id2: ["somedata1", "somedata2"]
    },
    z: {
      id2: ["somedata1", "somedata2"]
    }
  },
  thirdParam: {
    x: {
      id2: ["somedata1", "somedata2"]
    },
    y: {
      id2: ["somedata1", "somedata2"]
    },
    z: {
      id2: ["somedata1", "somedata2"]
    }
  }
}

const merge = (result, newObj) => {
  console.time("test merge")
  Object.keys(result).forEach(key => {
    result[key] = {
      x: {
        ...result[key].x,
        ...newObj[key].x
      },
      y: {
        ...result[key].y,
        ...newObj[key].y
      },
      z: {
        ...result[key].z,
        ...newObj[key].z
      }
    }
  })
  console.timeEnd("test merge")

  return result;
}

merge(result, newObj1);
</code>```

This solution gives me an expected result(I'm getting an obj2, obj3 ... objn and every iteration I'm merging it to result), but when I'm getting more than 500 or 1000 newObj it works pretty slow. Is there any way to optimize it?

答:
I assume you don't know the key naming of id1, id2, id3 ...

The performance issue is the spread operator, using a loop to get the key name and then executing only the needed substitution will make your code much faster.

```<code>import { Suite } from 'benchmark';

let suite = new Suite();

const result = {
    firstParam: {
        x: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        y: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        z: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        }
    },
    secondParam: {
        x: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        y: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        z: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        }
    },
    thirdParam: {
        x: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        y: {
            uuid1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        z: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        }
    }
}

const newObj1 = {
    firstParam: {
        x: {
            id2: ["somedata1", "somedata2"]
        },
        y: {
            id2: ["somedata1", "somedata2"]
        },
        z: {
            id2: ["somedata1", "somedata2"]
        }
    },
    secondParam: {
        x: {
            id2: ["somedata1", "somedata2"]
        },
        y: {
            id2: ["somedata1", "somedata2"]
        },
        z: {
            id2: ["somedata1", "somedata2"]
        }
    },
    thirdParam: {
        x: {
            id2: ["somedata1", "somedata2"]
        },
        y: {
            id2: ["somedata1", "somedata2"]
        },
        z: {
            id2: ["somedata1", "somedata2"]
        }
    }
}

const merge = (result: any, newObj: any) => {
    Object.keys(result).forEach(key => {
        result[key] = {
            x: {
                ...result[key].x,
                ...newObj[key].x
            },
            y: {
                ...result[key].y,
                ...newObj[key].y
            },
            z: {
                ...result[key].z,
                ...newObj[key].z
            }
        }
    })
    return result;
}

const mergeNoSpread = (result: any, newObj: any) => {
    Object.keys(result).forEach(key => {
        for (const key2 in newObj[key].x) {
            result[key].x[key2] = newObj[key].x[key2]
        }
        for (const key2 in newObj[key].y) {
            result[key].y[key2] = newObj[key].y[key2]
        }
        for (const key2 in newObj[key].z) {
            result[key].z[key2] = newObj[key].z[key2]
        }
    })

    return result;
}

suite
    .add('Spread usage', () => { merge(result, newObj1); })
    .add('No spread usage', () => { mergeNoSpread(result, newObj1); })
    .on('cycle', function (event: any) {
        console.log(String(event.target));
    })
    .on('complete', function () {
        console.log('Fastest is: ' + this.filter('fastest').map('name'));
    }).run({ 'async': true });

</code>```

The performance results:

```<code>Spread usage x 794,766 ops/sec ±1.43% (87 runs sampled)
No spread usage x 2,176,879 ops/sec ±0.78% (88 runs sampled)
Fastest is: No spread usage
</code>```

One iteration using console.time:

```<code>test merge: 0.252ms
test merge: 0.088ms
</code>```

Title: Merge two objects(optimizing)

Body:
I have n objects(with some nested structure). In the end, I'm expecting to get one merged object with all fields.

const result = {
  firstParam: {
    x: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    y: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    z: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    }
  },
  secondParam: {
    x: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    y: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    z: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    }
  },
  thirdParam: {
    x: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    y: {
      uuid1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    z: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    }
  }
}

const newObj1 = {
  firstParam: {
    x: {
      id2: ["somedata1", "somedata2"]
    },
    y: {
      id2: ["somedata1", "somedata2"]
    },
    z: {
      id2: ["somedata1", "somedata2"]
    }
  },
  secondParam: {
    x: {
      id2: ["somedata1", "somedata2"]
    },
    y: {
      id2: ["somedata1", "somedata2"]
    },
    z: {
      id2: ["somedata1", "somedata2"]
    }
  },
  thirdParam: {
    x: {
      id2: ["somedata1", "somedata2"]
    },
    y: {
      id2: ["somedata1", "somedata2"]
    },
    z: {
      id2: ["somedata1", "somedata2"]
    }
  }
}

const merge = (result, newObj) => {
  console.time("test merge")
  Object.keys(result).forEach(key => {
    result[key] = {
      x: {
        ...result[key].x,
        ...newObj[key].x
      },
      y: {
        ...result[key].y,
        ...newObj[key].y
      },
      z: {
        ...result[key].z,
        ...newObj[key].z
      }
    }
  })
  console.timeEnd("test merge")

  return result;
}

merge(result, newObj1);

This solution gives me an expected result(I'm getting an obj2, obj3 ... objn and every iteration I'm merging it to result), but when I'm getting more than 500 or 1000 newObj it works pretty slow. Is there any way to optimize it?

Body:
I assume you don't know the key naming of id1, id2, id3 ...

The performance issue is the spread operator, using a loop to get the key name and then executing only the needed substitution will make your code much faster.

import { Suite } from 'benchmark';

let suite = new Suite();

const result = {
    firstParam: {
        x: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        y: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        z: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        }
    },
    secondParam: {
        x: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        y: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        z: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        }
    },
    thirdParam: {
        x: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        y: {
            uuid1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        z: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        }
    }
}

const newObj1 = {
    firstParam: {
        x: {
            id2: ["somedata1", "somedata2"]
        },
        y: {
            id2: ["somedata1", "somedata2"]
        },
        z: {
            id2: ["somedata1", "somedata2"]
        }
    },
    secondParam: {
        x: {
            id2: ["somedata1", "somedata2"]
        },
        y: {
            id2: ["somedata1", "somedata2"]
        },
        z: {
            id2: ["somedata1", "somedata2"]
        }
    },
    thirdParam: {
        x: {
            id2: ["somedata1", "somedata2"]
        },
        y: {
            id2: ["somedata1", "somedata2"]
        },
        z: {
            id2: ["somedata1", "somedata2"]
        }
    }
}

const merge = (result: any, newObj: any) => {
    Object.keys(result).forEach(key => {
        result[key] = {
            x: {
                ...result[key].x,
                ...newObj[key].x
            },
            y: {
                ...result[key].y,
                ...newObj[key].y
            },
            z: {
                ...result[key].z,
                ...newObj[key].z
            }
        }
    })
    return result;
}

const mergeNoSpread = (result: any, newObj: any) => {
    Object.keys(result).forEach(key => {
        for (const key2 in newObj[key].x) {
            result[key].x[key2] = newObj[key].x[key2]
        }
        for (const key2 in newObj[key].y) {
            result[key].y[key2] = newObj[key].y[key2]
        }
        for (const key2 in newObj[key].z) {
            result[key].z[key2] = newObj[key].z[key2]
        }
    })

    return result;
}

suite
    .add('Spread usage', () => { merge(result, newObj1); })
    .add('No spread usage', () => { mergeNoSpread(result, newObj1); })
    .on('cycle', function (event: any) {
        console.log(String(event.target));
    })
    .on('complete', function () {
        console.log('Fastest is: ' + this.filter('fastest').map('name'));
    }).run({ 'async': true });

The performance results:

Spread usage x 794,766 ops/sec ±1.43% (87 runs sampled)
No spread usage x 2,176,879 ops/sec ±0.78% (88 runs sampled)
Fastest is: No spread usage

One iteration using console.time:

test merge: 0.252ms
test merge: 0.088ms


问:
Azure Pipelines: Dotnet publish fails with exit code 1 after migrating to .NET Core 3.1
I have an Azure Pipeline which is setup to do:

Use .NET Core SDK 3.1.x

Dotnet restore

Dotnet Build

Dotnet Publish

Use .NET Core task looks like that and it run before all others mentioned above:

All the jobs are executed successfully apart the Dotnet Publish

This job crashes with these errors:

AND

[error]Error: The process 'C:\hostedtoolcache\windows\dotnet\dotnet.exe' failed with exit code 1

[warning]Info: Azure Pipelines hosted agents have been updated to contain .Net Core 3.x SDK/Runtime along with 2.2 & 2.1. Unless you have locked down a SDK version for your project(s), 3.x SDK might be picked up which might have breaking behavior as compared to previous versions.

I tried different version variation for Use .NET Core SDK Job, however all of them lead to the same error.

Publish job:

Thanks in advance. Appreciate if someone could give me a clue what I might be doing wrong.

答:
Found out that issue had nothing to do with the Azure Pipelines, it was caused by the package referenced in my .csproj:

```<code><DotNetCliToolReference Include="Microsoft.DotNet.Xdt.Tools" Version="2.0.0" />
</code>```

This package has a dependency for .NETCoreApp 2.0

Found that author created a new package:
https://www.nuget.org/packages/DotNet.Xdt#
https://github.com/nil4/dotnet-transform-xdt

Which is now compatible with .NET Core 3.x

Body:
Found out that issue had nothing to do with the Azure Pipelines, it was caused by the package referenced in my .csproj:

<DotNetCliToolReference Include="Microsoft.DotNet.Xdt.Tools" Version="2.0.0" />

This package has a dependency for .NETCoreApp 2.0

Found that author created a new package:
https://www.nuget.org/packages/DotNet.Xdt#
https://github.com/nil4/dotnet-transform-xdt

Which is now compatible with .NET Core 3.x


问:
Get loading spinner visibility using isDisplay method-Protractor
My testcase is to click on a checkbox & soon after its checked there is a spinner progress animation shown which i want to assert if displayed. Using isDisplayed() method always returns me false after clicking on checkbox and my testcase fails, although i could see the spinner animation loading on UI.

Tried the below code which is failing:

```<code>var checkbox = element(by.id("crucial-one"));
browser.wait(EC.presenceOf(checkbox),5000);
checkbox.click();
var spinner = element(by.id("loading-spinner"));
spinner.isDisplayed().then(function(text){
        console.log(text);
    });
expect(spinner.isDisplayed()).toBe(true);
</code>```

HTML code of spinner before clicking on checkbox:

```<code><body class="searches">
<div id="loading-spinner" class="wda-overlay" style="display: none;">
    <div class="progress-box" role="region">
        <div class="loader-container large">
            <svg class="loader" viewBox="25 25 50 50">
        </div>
    <div class="msg">Loading...</div>
    </div>
</div>
</code>```

HTML code of spinner after clicking on checkbox:

```<code><body class="searches">
<div id="loading-spinner" class="wda-overlay" style="display: block;">
    <div class="progress-box" role="region">
        <div class="loader-container large">
            <svg class="loader" viewBox="25 25 50 50">
        </div>
    <div class="msg">Loading...</div>
    </div>
</div>
</code>```

答:
I got the same problem. Answer from Marcin is right, you must use browser.wait() with the condition visibility.Of()

If the spinner display is short, also use browser.waitForAngularEnabled(false);

ContentLicense: CC BY-SA 3.0

Body:
My testcase is to click on a checkbox & soon after its checked there is a spinner progress animation shown which i want to assert if displayed. Using isDisplayed() method always returns me false after clicking on checkbox and my testcase fails, although i could see the spinner animation loading on UI.

Tried the below code which is failing:

var checkbox = element(by.id("crucial-one"));
browser.wait(EC.presenceOf(checkbox),5000);
checkbox.click();
var spinner = element(by.id("loading-spinner"));
spinner.isDisplayed().then(function(text){
        console.log(text);
    });
expect(spinner.isDisplayed()).toBe(true);

HTML code of spinner before clicking on checkbox:

            <svg class="loader" viewBox="25 25 50 50">

Loading...

HTML code of spinner after clicking on checkbox:

            <svg class="loader" viewBox="25 25 50 50">

Loading...


问:
How could we use a formula in query Google sheet
I am unable to figure out how could we use formula within query results. I did not find any solution yet.

Like:

```<code>=query(sheet1!A1:Z,"Select A,B,Vlookup(D,sheet1!A1:A,1,false)");
</code>```

答:
If your range is A1:Z, the column where you can insert the formula without error must be bigger than Z

Sheet formulas do not expect (nor allow) semicola at the end

If D is a string, it should be nested in double quotes

To combine your formulas, you need to combine the quotes correctly, e.g.:

```<code>=query(Sheet1!A1:Z, CONCATENATE("select A,B,",Vlookup("D",Sheet1!A1:A,1,false)))
</code>```

Body:
I am unable to figure out how could we use formula within query results. I did not find any solution yet.

Like:

=query(sheet1!A1:Z,"Select A,B,Vlookup(D,sheet1!A1:A,1,false)");

Body:
If your range is A1:Z, the column where you can insert the formula without error must be bigger than Z

Sheet formulas do not expect (nor allow) semicola at the end

If D is a string, it should be nested in double quotes

To combine your formulas, you need to combine the quotes correctly, e.g.:

=query(Sheet1!A1:Z, CONCATENATE("select A,B,",Vlookup("D",Sheet1!A1:A,1,false)))


问:
How to using character functions like "like" in Microsoft Azure Table Storage Query Editor?
I have a table with a lot of data that I don't need, but I have to save that, however to do my job i need only some data.
so, to limit the amount of data that my query will return I have to use a filter to not get some files like the strings .js, .css, .log etc.

I'm using the "Microsoft Azure Explorer - Azure Table Storage - Query Editor" to do this, but I don't know how to use a function like SQL function "like" to filter that strings.

follow a example of data that i don't need in my return:
lg.folha.views.demonstrativodemedias.editar.min.css
27042018_144634_536_6A2FAE_AMB..xml

is it possible to filter that files using only the query builder options?

Query Builder Options

Query builder documentation: https://learn.microsoft.com/en-us/rest/api/storageservices/Querying-Tables-and-Entities?redirectedfrom=MSDN#Anchor_2

答:
Fro now azure table doesn't support wildcard query. You could get it from here:Filtering on String Properties.

Note that the Table service does not support wildcard queries.

So you have to use eq, ne, gt, ge, lt, le these operators.

You could use property ge 'test'  and RowKey lt 'test~' to get query entities whose property starts with test.


问:
Response.isSuccessfull() is false
Help me out.
I am using retrofit for my project and I am totally new on it. I am getting the following error. Why I am getting a false response?

```<code>2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: Response
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush:
Response{protocol=http/1.1, code=402, message=Payment Required,
url=https://quizziyapa.herokuapp.com/getTopics}
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: Payment Required
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: okhttp3.ResponseBody$1@647c751
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: null
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: false
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: retrofit2.OkHttpCall$NoContentResponseBody@4f0bbb6
[Error][1]
</code>```

JSON Structure

This is my json structure.

```<code>{
    "topics": [
        {
            "_id": 2,
            "topic": "abc",
            "imageUrl": "abc12345"
        },
        {
            "_id": 3,
            "topic": "abc",
            "imageUrl": "abc12345"
        }
    ]
}
</code>```

Topic.java

My Model class

```<code>public class Topic {
    int _id;
    String topic;
    String imageUrl;

    public Topic(int _id, String topic, String imageUrl) {
        this._id = _id;
        this.topic = topic;
        this.imageUrl = imageUrl;
    }

    public int getId() {
        return _id;
    }

    public String getTopic() {
        return topic;
    }

    public String getImageUrl() {
        return imageUrl;
    }
}
</code>```

TopicResponse.java

JSON response class

```<code>public class TopicResponse {
    @SerializedName("topics")
    Topic[] topics;

    public TopicResponse(Topic[] topics) {
        this.topics = topics;
    }

    public Topic[] getTopics() {
        return topics;
    }
}
</code>```

IUserApi.java (API Interface)

```<code>public interface IUserApi {
    @GET("getTopics")
    Call<TopicResponse> getTop();
}
</code>```

MainActivity.java

```<code>Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://quizziyapa.herokuapp.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        IUserApi api =  retrofit.create(IUserApi.class);
        Call<TopicResponse> call= api.getTop();
        call.enqueue(new Callback<TopicResponse>() {
            @Override
            public void onResponse(Call<TopicResponse> call, Response<TopicResponse> response) {
                Log.d("Ayush", "Response");
                Log.d("Ayush", String.valueOf(response));
                Log.d("Ayush", String.valueOf(response.message()));
                Log.d("Ayush", String.valueOf(response.errorBody()));
                Log.d("Ayush", String.valueOf(response.body()));
                Log.d("Ayush", String.valueOf(response.isSuccessful()));
                Log.d("Ayush", String.valueOf(response.raw().body()));
            }

            @Override
            public void onFailure(Call<TopicResponse> call, Throwable t) {
                Log.d("Ayush", "Failed \n"+t.getMessage());
            }
        });
</code>```

Help me out what should I do to solve this issue?

答:
I think I have found a solution. This API is working perfectly fine over browser and Postman too. But if you notice on PostMan, the status is 402

As per MDN Web Docs

The HTTP 402 Payment Required is a nonstandard client error status response code that is reserved for future use.

Since, retrofit follows status code 200 as success, the response body in your case is null.

However, if you closely look at the debug console, the value (json) is present, but in the errorBody.

I am not sure why Heroku is sending 402 request, but as per ljk's answer, it seems your account is not fully activated.

You can further readout Retrofit Class Response,

Returns true if code() is in the range [200..300).

Title: Response.isSuccessfull() is false

Body:
Help me out.
I am using retrofit for my project and I am totally new on it. I am getting the following error. Why I am getting a false response?

2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: Response
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush:
Response{protocol=http/1.1, code=402, message=Payment Required,
url=https://quizziyapa.herokuapp.com/getTopics}
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: Payment Required
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: okhttp3.ResponseBody$1@647c751
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: null
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: false
2020-02-20 15:35:26.230 22602-22602/q.goaldiggers.auth_api_testing
D/Ayush: retrofit2.OkHttpCall$NoContentResponseBody@4f0bbb6
[Error][1]

JSON Structure

This is my json structure.

{
    "topics": [
        {
            "_id": 2,
            "topic": "abc",
            "imageUrl": "abc12345"
        },
        {
            "_id": 3,
            "topic": "abc",
            "imageUrl": "abc12345"
        }
    ]
}

Topic.java

My Model class

public class Topic {
    int _id;
    String topic;
    String imageUrl;

    public Topic(int _id, String topic, String imageUrl) {
        this._id = _id;
        this.topic = topic;
        this.imageUrl = imageUrl;
    }

    public int getId() {
        return _id;
    }

    public String getTopic() {
        return topic;
    }

    public String getImageUrl() {
        return imageUrl;
    }
}

TopicResponse.java

JSON response class

public class TopicResponse {
    @SerializedName("topics")
    Topic[] topics;

    public TopicResponse(Topic[] topics) {
        this.topics = topics;
    }

    public Topic[] getTopics() {
        return topics;
    }
}

IUserApi.java (API Interface)

public interface IUserApi {
    @GET("getTopics")
    Call<TopicResponse> getTop();
}

MainActivity.java

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://quizziyapa.herokuapp.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        IUserApi api =  retrofit.create(IUserApi.class);
        Call<TopicResponse> call= api.getTop();
        call.enqueue(new Callback<TopicResponse>() {
            @Override
            public void onResponse(Call<TopicResponse> call, Response<TopicResponse> response) {
                Log.d("Ayush", "Response");
                Log.d("Ayush", String.valueOf(response));
                Log.d("Ayush", String.valueOf(response.message()));
                Log.d("Ayush", String.valueOf(response.errorBody()));
                Log.d("Ayush", String.valueOf(response.body()));
                Log.d("Ayush", String.valueOf(response.isSuccessful()));
                Log.d("Ayush", String.valueOf(response.raw().body()));
            }

            @Override
            public void onFailure(Call<TopicResponse> call, Throwable t) {
                Log.d("Ayush", "Failed \n"+t.getMessage());
            }
        });

Help me out what should I do to solve this issue?


问:
Bootstrap Accordion | Heading click 2 div open with same ID
I am using bootstrap accordion. In this, you can expand and collapse one div according to their IDs but in my scenario, i want, two div expand and collapse. Both divs are not placed in same column both are placed in different column.

Here is the Example
https://codepen.io/nehaj804/pen/rNVMzax`

When Collapsible Group Item #1 heading click, then panel 1 text should show and hide..

答:
Is this what you are looking for? I have changed ID's to classes and used only one parent ID.

.row{
  display:flex;
}
.col-3{
  width:30%;
  display:inline-flex;
}
.col-9{
  width:70%;
  display:inline-flex;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row" id="accordion1">
  <div class="col-3">
    <div class="panel-group" id="accordion1">
      <div class="panel panel-default">
        <div class="panel-heading">
          <h4 class="panel-title">
            Collapsible Group Item #1

          </h4>
        </div>
        <div id="" class="collapseOne panel-collapse collapse in">
          <div class="panel-body">Panel 1</div>
        </div>
      </div>

      <div class="panel panel-default">
        <div class="panel-heading">
          <h4 class="panel-title">
            Collapsible Group Item #2

          </h4>
        </div>
        <div id="" class="collapseTwo panel-collapse collapse">
          <div class="panel-body">
            <div class="panel-body">
              <h2>Heading</h2>
              <div class="panel-group">
                <div class="panel">
                  View details 2.1 »

                  <div id="" class="collapseTwoOne panel-collapse collapse">
                    <div class="panel-body">Details 1</div>
                  </div>
                </div>
                <div class="panel ">
                  View details 2.2 »

                  <div id="" class="collapseTwoTwo panel-collapse collapse">
                    <div class="panel-body">Details 2</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div class="panel panel-default">
        <div class="panel-heading">
          <h4 class="panel-title">
            Collapsible Group Item #3

          </h4>
        </div>
        <div id="" class="collapseThree panel-collapse collapse">
          <div class="panel-body">

            <div class="panel-group" id="accordion1">
              <div class="panel panel-default">
                <div class="panel-heading">
                  <h4 class="panel-title">
                    Collapsible Group Item
                      #3.1

                  </h4>
                </div>
                <div id="" class="collapseThreeOne panel-collapse collapse in">
                  <div class="panel-body">Panel 3.1</div>
                </div>
              </div>
              <div class="panel panel-default">
                <div class="panel-heading">
                  <h4 class="panel-title">
                    Collapsible Group Item
                      #3.2

                  </h4>
                </div>
                <div id="" class="collapseThreeTwo panel-collapse collapse">
                  <div class="panel-body">Panel 3.2</div>
                </div>
              </div>
            </div>

          </div>
        </div>
      </div>

    </div>
  </div>
  <div class="col-9">
    <div id="" class="collapseOne panel-collapse collapse in">
      <div class="panel-body">Panel 1</div>
    </div>
    <div id="" class="collapseTwo panel-collapse collapse">
      <div class="panel-body">
        <div class="panel-body">
          <h2>Heading</h2>
          <div class="panel-group" id="">
            <div class="panel">
              View details 2.1 »

              <div id="" class="collapseTwoOne panel-collapse collapse">
                <div class="panel-body">Details 1</div>
              </div>
            </div>
            <div class="panel ">
              View details 2.2 »

              <div id="" class="collapseTwoTwo panel-collapse collapse">
                <div class="panel-body">Details 2</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div>
    </div></code>```

Body:
Is this what you are looking for? I have changed ID's to classes and used only one parent ID.

.row{
  display:flex;
}
.col-3{
  width:30%;
  display:inline-flex;
}
.col-9{
  width:70%;
  display:inline-flex;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row" id="accordion1">
  <div class="col-3">
    <div class="panel-group" id="accordion1">
      <div class="panel panel-default">
        <div class="panel-heading">
          <h4 class="panel-title">
            <a data-toggle="collapse" data-parent="#accordion1" href=".collapseOne">Collapsible Group Item #1
            </a>
          </h4>
        </div>
        <div id="" class="collapseOne panel-collapse collapse in">
          <div class="panel-body">Panel 1</div>
        </div>
      </div>

      <div class="panel panel-default">
        <div class="panel-heading">
          <h4 class="panel-title">
            <a data-toggle="collapse" data-parent="#accordion1" href=".collapseTwo">Collapsible Group Item #2
            </a>
          </h4>
        </div>
        <div id="" class="collapseTwo panel-collapse collapse">
          <div class="panel-body">
            <div class="panel-body">
              <h2>Heading</h2>
              <div class="panel-group">
                <div class="panel">
                  <a data-toggle="collapse" data-parent="#accordion1" href=".collapseTwoOne">View details 2.1 &raquo;
                  </a>
                  <div id="" class="collapseTwoOne panel-collapse collapse">
                    <div class="panel-body">Details 1</div>
                  </div>
                </div>
                <div class="panel ">
                  <a data-toggle="collapse" data-parent="#accordion1" href=".collapseTwoTwo">View details 2.2 &raquo;
                  </a>
                  <div id="" class="collapseTwoTwo panel-collapse collapse">
                    <div class="panel-body">Details 2</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div class="panel panel-default">
        <div class="panel-heading">
          <h4 class="panel-title">
            <a data-toggle="collapse" data-parent="#accordion1" href=".collapseThree">Collapsible Group Item #3
            </a>
          </h4>
        </div>
        <div id="" class="collapseThree panel-collapse collapse">
          <div class="panel-body">

            <div class="panel-group" id="accordion1">
              <div class="panel panel-default">
                <div class="panel-heading">
                  <h4 class="panel-title">
                    <a data-toggle="collapse" data-parent="#accordion1" href=".collapseThreeOne">Collapsible Group Item
                      #3.1
                    </a>
                  </h4>
                </div>
                <div id="" class="collapseThreeOne panel-collapse collapse in">
                  <div class="panel-body">Panel 3.1</div>
                </div>
              </div>
              <div class="panel panel-default">
                <div class="panel-heading">
                  <h4 class="panel-title">
                    <a data-toggle="collapse" data-parent="#accordion1" href=".collapseThreeTwo">Collapsible Group Item
                      #3.2
                    </a>
                  </h4>
                </div>
                <div id="" class="collapseThreeTwo panel-collapse collapse">
                  <div class="panel-body">Panel 3.2</div>
                </div>
              </div>
            </div>

          </div>
        </div>
      </div>

    </div>
  </div>
  <div class="col-9">
    <div id="" class="collapseOne panel-collapse collapse in">
      <div class="panel-body">Panel 1</div>
    </div>
    <div id="" class="collapseTwo panel-collapse collapse">
      <div class="panel-body">
        <div class="panel-body">
          <h2>Heading</h2>
          <div class="panel-group" id="">
            <div class="panel">
              <a data-toggle="collapse" data-parent="#accordion1" href=".collapseTwoOne">View details 2.1 &raquo;
              </a>
              <div id="" class="collapseTwoOne panel-collapse collapse">
                <div class="panel-body">Details 1</div>
              </div>
            </div>
            <div class="panel ">
              <a data-toggle="collapse" data-parent="#accordion1" href=".collapseTwoTwo">View details 2.2 &raquo;
              </a>
              <div id="" class="collapseTwoTwo panel-collapse collapse">
                <div class="panel-body">Details 2</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div>
    </div>


问:
Loading image from xcassets causes assertion failure
I am using the xcassets folder to store themable images. For the default theme, the image is always present in the xcassets, but for other themes, the image is optional, which will result in the use of the default image.

Pseudo code:

```<code>struct ThemeImage {
    static let standard = UIImage(named: "default-logo")!

    static func themedImage(for theme: String) -> UIImage {
        return UIImage(named: "\(theme)-logo") ?? ThemeImage.standard
    }
}
</code>```

Now when I try to load the image for a theme, but the asset does not exist, the app will instantly crash, reporting the following error:

```<code>*** Assertion failure in -[_UIImageCGImageContent initWithCGImage:scale:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore_Sim/UIKit-3901.4.2/_UIImageContent.m:336
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Need an imageRef'
</code>```

The documentation clearly states

Returns

An object containing an unconfigured version of the image, or nil if the method could not find the specified image.

Does anyone know what is happening or why the app crashes instead of returning nil?

答:
The issue was related to the xcassets folder after all. I had some colours in the folder too, which had the same name as the image.

Meaning UIColor(named: "default-logo") and UIImage(named: "default-logo") will cause the application to crash, even though both resources are present and valid in the xcassets folder.

The name of these assets needs to be unique.

Body:
I am using the xcassets folder to store themable images. For the default theme, the image is always present in the xcassets, but for other themes, the image is optional, which will result in the use of the default image.

Pseudo code:

struct ThemeImage {
    static let standard = UIImage(named: "default-logo")!

    static func themedImage(for theme: String) -> UIImage {
        return UIImage(named: "\(theme)-logo") ?? ThemeImage.standard
    }
}

Now when I try to load the image for a theme, but the asset does not exist, the app will instantly crash, reporting the following error:

*** Assertion failure in -[_UIImageCGImageContent initWithCGImage:scale:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore_Sim/UIKit-3901.4.2/_UIImageContent.m:336
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Need an imageRef'

The documentation clearly states

Returns

An object containing an unconfigured version of the image, or nil if the method could not find the specified image.

Does anyone know what is happening or why the app crashes instead of returning nil?


问:
Validate URL in android over network call
I am making an app where i have a url with date.I need to check if the url has data and if it had data then add date to list.I have made a method which i have posted below and it is being call on main thread.But the problem is it takes few seconds to start the app.I need to optimise the app.Is there any other way to "REDUCE THE LOADING TIME".

Code

```<code>   private List<String> getDateList(int counter, String date) {
 String urlth = "https://www.example.com/json/" + date.trim().replaceAll("/", "") + "-12.json";
    if (validateUrl.exists(urlth)) {
        dateList.add(date);
    } else {
        date = givePreviousDate(date);
        return getDateList(counter, date);
    }
    if (dateList.size() == 7) {
        return dateList;
    } else {
        date = givePreviousDate(date);  //gives previous date
        return getDateList(++counter, (date));
    }
}
</code>```

答:
You can use a handler to call your method in background, something like this

```<code>Handler handler = new Handler();
ListView<String> myList = new ArrayList<>();

handler.post(new Runnable() {
    @Override
    public void run() {
        //call your method here
        myList = getDateList(2, "date"); //with int and date data
    }
});
</code>```

Hope this will help!

Body:
I am making an app where i have a url with date.I need to check if the url has data and if it had data then add date to list.I have made a method which i have posted below and it is being call on main thread.But the problem is it takes few seconds to start the app.I need to optimise the app.Is there any other way to "REDUCE THE LOADING TIME".

Code

   private List<String> getDateList(int counter, String date) {
 String urlth = "https://www.example.com/json/" + date.trim().replaceAll("/", "") + "-12.json";
    if (validateUrl.exists(urlth)) {
        dateList.add(date);
    } else {
        date = givePreviousDate(date);
        return getDateList(counter, date);
    }
    if (dateList.size() == 7) {
        return dateList;
    } else {
        date = givePreviousDate(date);  //gives previous date
        return getDateList(++counter, (date));
    }
}

Body:
You can use a handler to call your method in background, something like this

Handler handler = new Handler();
ListView<String> myList = new ArrayList<>();

handler.post(new Runnable() {
    @Override
    public void run() {
        //call your method here
        myList = getDateList(2, "date"); //with int and date data
    }
});

Hope this will help!


问:
Trying to install perl's Catalyst framework on debian 6. - Can't use an undefined value as a HASH
```<code>[14:27: /mnt/mydocuments/git_working_dir/cat_example$] catalyst.pl hello_world
Couldn't load class (Catalyst::Exception::Basic) because: Can't use an undefined value as a HASH reference at /usr/lib/perl5/MooseX/Role/WithOverloading/Meta/Role/Application.pm line 45.
Compilation failed in require at /usr/local/lib/perl/5.10.1/Class/MOP.pm line 117.
 at /usr/local/lib/perl/5.10.1/Class/MOP.pm line 123
    Class::MOP::__ANON__('Can\'t use an undefined value as a HASH reference at /usr/lib...') called at /usr/local/share/perl/5.10.1/Try/Tiny.pm line 100
    Try::Tiny::try('CODE(0x29021c8)', 'Try::Tiny::Catch=REF(0x28fca88)') called at /usr/local/lib/perl/5.10.1/Class/MOP.pm line 128
    Class::MOP::load_first_existing_class('Catalyst::Exception::Basic') called at /usr/local/lib/perl/5.10.1/Class/MOP.pm line 140
    Class::MOP::load_class('Catalyst::Exception::Basic', undef) called at /usr/local/lib/perl/5.10.1/Moose/Util.pm line 126
    Moose::Util::_apply_all_roles('Moose::Meta::Class=HASH(0x2b63fe0)', undef, 'Catalyst::Exception::Basic') called at /usr/local/lib/perl/5.10.1/Moose/Util.pm line 93
    Moose::Util::apply_all_roles('Moose::Meta::Class=HASH(0x2b63fe0)', 'Catalyst::Exception::Basic') called at /usr/local/lib/perl/5.10.1/Moose.pm line 60
    Moose::with('Moose::Meta::Class=HASH(0x2b63fe0)', 'Catalyst::Exception::Basic') called at /usr/local/lib/perl/5.10.1/Moose/Exporter.pm line 356
    Moose::with('Catalyst::Exception::Basic') called at /usr/share/perl5/Catalyst/Exception.pm line 50
    require Catalyst/Exception.pm called at /usr/share/perl5/Catalyst/Utils.pm line 4
    Catalyst::Utils::BEGIN() called at /usr/share/perl5/Catalyst/Exception.pm line 0
    eval {...} called at /usr/share/perl5/Catalyst/Exception.pm line 0
    require Catalyst/Utils.pm called at /usr/share/perl5/Catalyst/Helper.pm line 12
    Catalyst::Helper::BEGIN() called at /usr/share/perl5/Catalyst/Exception.pm line 0
    eval {...} called at /usr/share/perl5/Catalyst/Exception.pm line 0
    require Catalyst/Helper.pm called at /usr/bin/catalyst.pl line 26
    main::BEGIN() called at /usr/share/perl5/Catalyst/Exception.pm line 0
    eval {...} called at /usr/share/perl5/Catalyst/Exception.pm line 0
Compilation failed in require at /usr/share/perl5/Catalyst/Utils.pm line 4.
BEGIN failed--compilation aborted at /usr/share/perl5/Catalyst/Utils.pm line 4.
Compilation failed in require at /usr/share/perl5/Catalyst/Helper.pm line 12.
BEGIN failed--compilation aborted at /usr/share/perl5/Catalyst/Helper.pm line 12.
Compilation failed in require at /usr/bin/catalyst.pl line 26.
BEGIN failed--compilation aborted at /usr/bin/catalyst.pl line 26.
[14:27: /mnt/mydocuments/git_working_dir/cat_example$]
</code>```

答:
You don't describe, how you tried to install?

There is many ways, i'd like to stick to package manager, so just:

sudo apt-get install libcatalyst-perl

Update:
Your problem is certainly in mixed use of CPAN and Debian packages. You must get rid of one and you get it working.


问:
Vertical Bootstrap Nav will not fill width of CSS Grid parent element
Here is a JS Fiddle of the problem for reference:
https://jsfiddle.net/ncoughlin/1fjxy230/4/

I am having an issue where I am trying to get a vertical bootstrap nav menu to inherit the width of it's parent element, which is a CSS Grid column. For the sake of troubleshooting I have put the background of the grid column to red. So I am essentially trying to get the dark gray vertical nav on the left hand side to match the width of the red Grid column.

The bootstrap nav has id #settings-nav

I have tried the basic stuff like adding the bootstrap class w-100 to the nav ul or in the stylesheet adding width: 100%; however both of these make the menu stretch over the entire viewport instead of the parent element, which is the Grid column. It's behaving like the Grid column is not it's parent element, but using inspector I know that it is...

Please let me know where I am going wrong here. Thank you.

答: The problem ended up being that the #settings-nav was set to position:absolute, which makes it so that it ignores the dimensions of the parent element. Changed to position:relative and it works perfectly.


问:
Crash on device during language change in cocos2dJs cross platform game (in Android Platform)
We are getting a crash whenever user changes device language & if game is in background. we are using cocos2dJs3.17.1 to build our games. It seems it is framework issue because to test this scenario we created new blank project & tried the same thing, it crashed.

Steps to produce the crash :

Open the game.

Go to device settings & change the language.

Open the background game (that is there in background )

Click some buttons in game ( you should have some button that have some touch events )

game will crash once you click any button.

Stack trace from adb logcat:

```<code>01-31 12:10:57.814  6212  6451 W cr_ChildProcessConn: onServiceDisconnected (crash or killed by oom): pid=6454
01-31 12:10:57.998  6212  6212 E chromium: [ERROR:aw_browser_terminator.cc(125)] Renderer process (6454) crash detected (code -1).
01-31 12:10:58.026  6212  6212 E chromium: [ERROR:aw_browser_terminator.cc(90)] Render process (6454) kill (OOM or update) wasn't handed by all associated webviews, killing application.
01-31 12:10:58.183  3544  3544 I Zygote  : Process 6212 exited due to signal (9)
01-31 12:10:58.201  3926  4301 I ActivityManager: Process com.x.x (pid 6212) has died: cch+1CAC (117,340)"
</code>```

Any idea or solution please do share in this thread.

答:
It would be better to manually restart the app in those cases.
You can change the main activity slightly as follows:

```<code>private final String TRIGGER_REBIRTH = "trigger_rebirth";

@Override
protected void onCreate(Bundle savedInstanceState) {
  if (savedInstanceState != null) {
     if (savedInstanceState.getBoolean(TRIGGER_REBIRTH, false)) {
        // Trigger app restart here
        // See Implementation - https://github.com/JakeWharton/ProcessPhoenix
        ProcessPhoenix.triggerRebirth(this, getIntent());
     }
  }
}

@Override
public void onSaveInstanceState(Bundle outState) {
  outState.putBoolean(TRIGGER_REBIRTH, true);
}
</code>```

Also prevents the Cocos2d-x JS engine crash, JS_AbortIfWrongThread which happens after user navigates to app which was killed by android while in background.

Body:
We are getting a crash whenever user changes device language & if game is in background. we are using cocos2dJs3.17.1 to build our games. It seems it is framework issue because to test this scenario we created new blank project & tried the same thing, it crashed.

Steps to produce the crash :

Open the game.

Go to device settings & change the language.

Open the background game (that is there in background )

Click some buttons in game ( you should have some button that have some touch events )

game will crash once you click any button.

Stack trace from adb logcat:

01-31 12:10:57.814  6212  6451 W cr_ChildProcessConn: onServiceDisconnected (crash or killed by oom): pid=6454
01-31 12:10:57.998  6212  6212 E chromium: [ERROR:aw_browser_terminator.cc(125)] Renderer process (6454) crash detected (code -1).
01-31 12:10:58.026  6212  6212 E chromium: [ERROR:aw_browser_terminator.cc(90)] Render process (6454) kill (OOM or update) wasn't handed by all associated webviews, killing application.
01-31 12:10:58.183  3544  3544 I Zygote  : Process 6212 exited due to signal (9)
01-31 12:10:58.201  3926  4301 I ActivityManager: Process com.x.x (pid 6212) has died: cch+1CAC (117,340)"

Any idea or solution please do share in this thread.

Body:
It would be better to manually restart the app in those cases.
You can change the main activity slightly as follows:

private final String TRIGGER_REBIRTH = "trigger_rebirth";

@Override
protected void onCreate(Bundle savedInstanceState) {
  if (savedInstanceState != null) {
     if (savedInstanceState.getBoolean(TRIGGER_REBIRTH, false)) {
        // Trigger app restart here
        // See Implementation - https://github.com/JakeWharton/ProcessPhoenix
        ProcessPhoenix.triggerRebirth(this, getIntent());
     }
  }
}

@Override
public void onSaveInstanceState(Bundle outState) {
  outState.putBoolean(TRIGGER_REBIRTH, true);
}

Also prevents the Cocos2d-x JS engine crash, JS_AbortIfWrongThread which happens after user navigates to app which was killed by android while in background.


问:
how to get firebase time in firebase
I needed in my app firebase (server) time millisecond. because my local time will be change by mobile date time setting,

i will be see this question by not so helpful,
Flutter Firestore Server side Timestamp

```<code>var timestamp=FieldValue.serverTimestamp();

print("timestamp"+timestamp.toString());
</code>```

but they print below value

```<code>====>Instance of 'FieldValue'
</code>```

答:
you should use </p>

```<code>timestamp() {
    Firestore.instance.collection('timestamp').document('time').setData({
      "timestamp": FieldValue.serverTimestamp(),
    });
  }
</code>```

Title: how to get firebase time in firebase

Body:
I needed in my app firebase (server) time millisecond. because my local time will be change by mobile date time setting,

i will be see this question by not so helpful,
Flutter Firestore Server side Timestamp

var timestamp=FieldValue.serverTimestamp();

print("timestamp"+timestamp.toString());

but they print below value

====>Instance of 'FieldValue'

Body:
you should use

timestamp() {
    Firestore.instance.collection('timestamp').document('time').setData({
      "timestamp": FieldValue.serverTimestamp(),
    });
  }


问:
Rails, post-deploy to Heroku: unable to run console, db:migrate
Good day,

My team and I are trying to push our Rails app to Heroku - git push heroku dev:master is successful, but thereafter heroku run rails db:migrate, heroku run rails console, etc. all fail with the following error (full trace pasted at bottom of post):

```<code>   NoMethodError: undefined method `map' for nil:NilClass
    /app/vendor/bundle/ruby/2.4.0/gems/warden-jwt_auth-0.3.6/lib/warden/jwt_auth.rb:89:in `upcase_first_items'
</code>```

I tracked down the failing method upcase_first_items in the files of the gem jwt_auth, but remain unable to solve this. Searching the error on Google (including iterations of the error) turns up 0 results.

We successfully pushed this app to Heroku two weeks ago, and have not since changed anything with regards to authentication (which I've made sure of by reviewing all our commits from the last 2 weeks).

Any ideas?

Thanks,
Michael

Full trace:

```<code>[cocomio-languages (dev)]$ heroku run rails db:migrate --trace
Running rails db:migrate --trace on ⬢ coco-sprint-3... up, run.2956 (Hobby)
** Invoke db:migrate (first_time)
** Invoke db:load_config (first_time)
** Invoke environment (first_time)
** Execute environment
rails aborted!
NoMethodError: undefined method `map' for nil:NilClass
/app/vendor/bundle/ruby/2.4.0/gems/warden-jwt_auth-0.3.6/lib/warden/jwt_auth.rb:89:in `upcase_first_items'
/app/vendor/bundle/ruby/2.4.0/gems/warden-jwt_auth-0.3.6/lib/warden/jwt_auth.rb:50:in `block in <module:JWTAuth>'
/app/vendor/bundle/ruby/2.4.0/gems/dry-configurable-0.11.1/lib/dry/configurable/setting.rb:119:in `evaluate'
/app/vendor/bundle/ruby/2.4.0/gems/dry-configurable-0.11.1/lib/dry/configurable/setting.rb:70:in `value'
/app/vendor/bundle/ruby/2.4.0/gems/dry-configurable-0.11.1/lib/dry/configurable/config.rb:111:in `method_missing'
/app/vendor/bundle/ruby/2.4.0/gems/devise-jwt-0.5.9/lib/devise/jwt/railtie.rb:19:in `block (3 levels) in <class:Railtie>'
/app/vendor/bundle/ruby/2.4.0/gems/dry-configurable-0.11.1/lib/dry/configurable/methods.rb:15:in `configure'
/app/vendor/bundle/ruby/2.4.0/gems/devise-jwt-0.5.9/lib/devise/jwt/railtie.rb:15:in `block (2 levels) in <class:Railtie>'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:69:in `block in execute_hook'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:62:in `with_execution_control'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:67:in `execute_hook'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:51:in `each'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/application/finisher.rb:75:in `block in <module:Finisher>'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/initializable.rb:32:in `instance_exec'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/initializable.rb:32:in `run'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/initializable.rb:61:in `block in run_initializers'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:228:in `block in tsort_each'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:431:in `each_strongly_connected_component_from'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:349:in `block in each_strongly_connected_component'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:347:in `each'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:347:in `call'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:347:in `each_strongly_connected_component'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:226:in `tsort_each'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:205:in `tsort_each'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/initializable.rb:60:in `run_initializers'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/application.rb:361:in `initialize!'
/app/config/environment.rb:5:in `<main>'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:291:in `block in require'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:257:in `load_dependency'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:291:in `require'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/application.rb:337:in `require_environment!'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/application.rb:520:in `block in run_tasks_blocks'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `block in execute'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `each'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `execute'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:199:in `invoke_with_call_chain'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:243:in `block in invoke_prerequisites'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:241:in `each'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:241:in `invoke_prerequisites'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:218:in `block in invoke_with_call_chain'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:199:in `invoke_with_call_chain'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:243:in `block in invoke_prerequisites'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:241:in `each'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:241:in `invoke_prerequisites'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:218:in `block in invoke_with_call_chain'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:199:in `invoke_with_call_chain'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:188:in `invoke'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:160:in `invoke_task'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `each'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `block in top_level'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:125:in `run_with_threads'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:110:in `top_level'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/commands/rake/rake_command.rb:23:in `block in perform'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:186:in `standard_exception_handling'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/commands/rake/rake_command.rb:20:in `perform'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/command.rb:48:in `invoke'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/commands.rb:18:in `<main>'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:291:in `block in require'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:257:in `load_dependency'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:291:in `require'
/app/bin/rails:4:in `<main>'
Tasks: TOP => db:migrate => db:load_config => environment
</code>```

Update 1

I reverted to each commit from the previous two weeks (i.e. between now and the last working deploy), and deployed, but received the same error. I reached commits from even before the last deploy (the deploy that was working), and still have the same error, which leads me to believe it has nothing to do with our commits from the last few weeks.

When I went to the Heroku dashboard and reverted the build to the deploy from two weeks ago, the Rails commands (heroku run rails c, heroku run rails db:migrate, etc.) once again work.

答:
With the version 0.8.0 of devise-jwt it's no longer a problem. Please see the breaking change in version 0.7.0, when upgrading.

Previous answer

Probably someone or something upgraded the dry-configurable gem from version 0.9.0 to 0.11.1. This gem is a dependency of warden-jwt_auth which is a dependency of devise-jwt and the new version breaks it.

A few days ago the version 0.11.0 of dry-configurable was released and warden-jwt_auth uses it, because it specifies the version of this dependency with ~> 0.6, which includes the faulty version (everything from 0.6 to 1.0 would be fine). You can see that in the Gemfile.lock or in the dependencies of warden-jwt_auth.

If somebody did run bundle upgrade it will have pulled the new faulty version.

I recommend you to pin the older version of dry-configurable in your Gemfile:

```<code>gem 'dry-configurable', '0.9.0'
</code>```

Then run bundle update and deploy again.

Body:
Good day,

My team and I are trying to push our Rails app to Heroku - git push heroku dev:master is successful, but thereafter heroku run rails db:migrate, heroku run rails console, etc. all fail with the following error (full trace pasted at bottom of post):

   NoMethodError: undefined method `map' for nil:NilClass
    /app/vendor/bundle/ruby/2.4.0/gems/warden-jwt_auth-0.3.6/lib/warden/jwt_auth.rb:89:in `upcase_first_items'

I tracked down the failing method upcase_first_items in the files of the gem jwt_auth, but remain unable to solve this. Searching the error on Google (including iterations of the error) turns up 0 results.

We successfully pushed this app to Heroku two weeks ago, and have not since changed anything with regards to authentication (which I've made sure of by reviewing all our commits from the last 2 weeks).

Any ideas?

Thanks,
Michael

Full trace:

[cocomio-languages (dev)]$ heroku run rails db:migrate --trace
Running rails db:migrate --trace on ⬢ coco-sprint-3... up, run.2956 (Hobby)
** Invoke db:migrate (first_time)
** Invoke db:load_config (first_time)
** Invoke environment (first_time)
** Execute environment
rails aborted!
NoMethodError: undefined method `map' for nil:NilClass
/app/vendor/bundle/ruby/2.4.0/gems/warden-jwt_auth-0.3.6/lib/warden/jwt_auth.rb:89:in `upcase_first_items'
/app/vendor/bundle/ruby/2.4.0/gems/warden-jwt_auth-0.3.6/lib/warden/jwt_auth.rb:50:in `block in <module:JWTAuth>'
/app/vendor/bundle/ruby/2.4.0/gems/dry-configurable-0.11.1/lib/dry/configurable/setting.rb:119:in `evaluate'
/app/vendor/bundle/ruby/2.4.0/gems/dry-configurable-0.11.1/lib/dry/configurable/setting.rb:70:in `value'
/app/vendor/bundle/ruby/2.4.0/gems/dry-configurable-0.11.1/lib/dry/configurable/config.rb:111:in `method_missing'
/app/vendor/bundle/ruby/2.4.0/gems/devise-jwt-0.5.9/lib/devise/jwt/railtie.rb:19:in `block (3 levels) in <class:Railtie>'
/app/vendor/bundle/ruby/2.4.0/gems/dry-configurable-0.11.1/lib/dry/configurable/methods.rb:15:in `configure'
/app/vendor/bundle/ruby/2.4.0/gems/devise-jwt-0.5.9/lib/devise/jwt/railtie.rb:15:in `block (2 levels) in <class:Railtie>'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:69:in `block in execute_hook'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:62:in `with_execution_control'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:67:in `execute_hook'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:51:in `each'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/application/finisher.rb:75:in `block in <module:Finisher>'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/initializable.rb:32:in `instance_exec'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/initializable.rb:32:in `run'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/initializable.rb:61:in `block in run_initializers'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:228:in `block in tsort_each'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:431:in `each_strongly_connected_component_from'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:349:in `block in each_strongly_connected_component'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:347:in `each'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:347:in `call'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:347:in `each_strongly_connected_component'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:226:in `tsort_each'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/tsort.rb:205:in `tsort_each'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/initializable.rb:60:in `run_initializers'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/application.rb:361:in `initialize!'
/app/config/environment.rb:5:in `'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:291:in `block in require'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:257:in `load_dependency'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:291:in `require'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/application.rb:337:in `require_environment!'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/application.rb:520:in `block in run_tasks_blocks'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `block in execute'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `each'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `execute'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:199:in `invoke_with_call_chain'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:243:in `block in invoke_prerequisites'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:241:in `each'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:241:in `invoke_prerequisites'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:218:in `block in invoke_with_call_chain'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:199:in `invoke_with_call_chain'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:243:in `block in invoke_prerequisites'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:241:in `each'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:241:in `invoke_prerequisites'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:218:in `block in invoke_with_call_chain'
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/monitor.rb:214:in `mon_synchronize'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:199:in `invoke_with_call_chain'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/task.rb:188:in `invoke'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:160:in `invoke_task'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `each'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `block in top_level'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:125:in `run_with_threads'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:110:in `top_level'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/commands/rake/rake_command.rb:23:in `block in perform'
/app/vendor/bundle/ruby/2.4.0/gems/rake-13.0.1/lib/rake/application.rb:186:in `standard_exception_handling'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/commands/rake/rake_command.rb:20:in `perform'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/command.rb:48:in `invoke'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.2.4.1/lib/rails/commands.rb:18:in `'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
/app/vendor/bundle/ruby/2.4.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:291:in `block in require'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:257:in `load_dependency'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.2.4.1/lib/active_support/dependencies.rb:291:in `require'
/app/bin/rails:4:in `'
Tasks: TOP => db:migrate => db:load_config => environment

Update 1

I reverted to each commit from the previous two weeks (i.e. between now and the last working deploy), and deployed, but received the same error. I reached commits from even before the last deploy (the deploy that was working), and still have the same error, which leads me to believe it has nothing to do with our commits from the last few weeks.

When I went to the Heroku dashboard and reverted the build to the deploy from two weeks ago, the Rails commands (heroku run rails c, heroku run rails db:migrate, etc.) once again work.

Body:
With the version 0.8.0 of devise-jwt it's no longer a problem. Please see the breaking change in version 0.7.0, when upgrading.

Previous answer

Probably someone or something upgraded the dry-configurable gem from version 0.9.0 to 0.11.1. This gem is a dependency of warden-jwt_auth which is a dependency of devise-jwt and the new version breaks it.

A few days ago the version 0.11.0 of dry-configurable was released and warden-jwt_auth uses it, because it specifies the version of this dependency with ~> 0.6, which includes the faulty version (everything from 0.6 to 1.0 would be fine). You can see that in the Gemfile.lock or in the dependencies of warden-jwt_auth.

If somebody did run bundle upgrade it will have pulled the new faulty version.

I recommend you to pin the older version of dry-configurable in your Gemfile:

gem 'dry-configurable', '0.9.0'

Then run bundle update and deploy again.