问:
multiple calls to template versus calls inside ng-repeat
I'm working on migrating a HUGE angular form to a new layout (can't change technologies). The current version is drawn from a huge nasty javascript array that gets fed into an ng-repeat and calls various templates. The templates aren't changing in the new form except for some new css stuff. The new/old path that angular follows to generate the form html is controlled by a server side feature toggle (not really import to this question).

For the form, the only difference now is I'm not in a ng-repeat loop and instead I'm doing a ng-include multiple times in a more well defined layout.

The problem I'm having is the values being passed into each ng-include elements only get the ng-init values of the last call on the page, see example below..

```<code><!-- begin template definitions -->
<script type="text/ng-template" id="/templates/currency.html">
    <ul class="input-field-layout">
        <li>
            <input type="text" class="form-control {{field.additionalClasses}}" id="input_{{field.name}}"
                   ng-class="{{field.ngClass}}"
                   ng-model="$ctrl.contract[field.name]"
                   ng-disabled="field.disabled && !$ctrl.overrideSelected"
                   ng-change="field.onChange()"
                   ng-blur="field.onBlur()"
                   ng-readonly="field.readOnly"
            />
            <span class="input-group-btn" ng-if="field.showCalculator && field.canCalculate()">
                <button type="button" class="btn btn-default btn-sm"
                        id="calc_{{field.name}}"
                        ng-click="field.calculate()"
                        tabindex="-1"
                >
                    <i class="glyphicon glyphicon-flash"></i>
                </button>
            </span>
        </li>
        <li class="input-description-text" ng-if="field.descriptionText">
            <span>{{field.descriptionText}}</span>
        </li>
    </ul>
</script>
<!-- end template definitions -->

<!-- begin snippet for old form -->
<div ng-repeat="fieldGroup in $ctrl.fieldGroups">
    <div class="clearfix" ng-if="fieldGroup.clearFixClass == true"></div>
    <div>
        <h3>{{fieldGroup.name}}</h3>
        <hr>
        <div class="form-group form-group-sm"
             ng-repeat="field in fieldGroup.fields">
            <label class="control-label {{field.additionalClasses}}" for="input_{{field.name}}">{{field.field_label}}</label>
            <div ng-include="'/templates/'+field.type+'.html'"></div>
        </div>
    </div>
</div>
<!-- begin snippet for old form -->

<!-- being snippet for new form -->
<div class="flexRow">
    <label class="boldInput" for="input_adjustment">Adjustment</label>
    <div
        ng-init="
        field = {
            name: 'adjustment'
        }
        "
        ng-include="'/templates/currency.html'">
    </div>
</div>
<div class="flexRow">
    <label class="boldInput" for="input_total_due">Total</label>
    <div
        ng-init="
        field = {
            name: 'total',
            descriptionText: 'blah blah blah',
            disabled: $ctrl.disabledCheck.disabled_fields,
            showCalculator: true,
            calculate: $ctrl.calculateTotal,
            canCalculate: $ctrl.canCalculateTotal,
            additionalClasses: 'boldInput'
        }
        "
        ng-include="'/templates/currency.html'">
    </div>
</div>
<!-- end snippet for new form -->
</code>```

The old logic generates what you'd expect, but the new logic generates the following. Notice how both fields have the id input_total and other attributes/values of the final call to the template on the page.

```<code><div class="flexRow">
    <label class="boldInput" for="input_adjustment">Adjustment</label>
    <ul class="input-field-layout ng-scope">
        <li>
            <input type="text" class="form-control boldInput ng-empty ng-touched" id="input_total" ng-class="" ng-model="$ctrl.contract[field.name]" ng-disabled="field.disabled">
            <!-- ngIf: field.showCalculator && field.canCalculate() -->
        </li>
        <!-- ngIf: field.descriptionText --><li class="input-description-text ng-scope" ng-if="field.descriptionText">
            <span class="ng-binding">blah blah blah</span>
        </li><!-- end ngIf: field.descriptionText -->
    </ul>
</div>
<div class="flexRow">
    <label class="boldInput" for="input_total">Total</label>
    <ul class="input-field-layout ng-scope">
        <li>
            <input type="text" class="form-control boldInput ng-empty ng-touched" id="input_total" ng-class="" ng-model="$ctrl.contract[field.name]" ng-disabled="field.disabled">
            <!-- i've removed the calculator html for sake of space in this question -->
        </li>
        <!-- ngIf: field.descriptionText --><li class="input-description-text ng-scope" ng-if="field.descriptionText">
            <span class="ng-binding">blah blah blah</span>
        </li><!-- end ngIf: field.descriptionText -->
    </ul>
</div>
</code>```

I feel like ng-init is not what I should be using to pass-in values for field to the templates in the new form logic, but Uncle Google is failing me.

What should I be using instead of ng-init or how does the scope(?) change inside an ng-repeat versus multiple calls to the templates?

答:
When you assign field = { ... } you're overwriting it the second time, which binds back to the initial template.

To do this type of "pass parameter to template" thing, you should really be using a directive or component.

The reason the ng-repeat works is because it creates its own scope for each iteration, meaning the init variable is bound to a different scope each time and doesn't get overwritten.

Body:
I'm working on migrating a HUGE angular form to a new layout (can't change technologies). The current version is drawn from a huge nasty javascript array that gets fed into an ng-repeat and calls various templates. The templates aren't changing in the new form except for some new css stuff. The new/old path that angular follows to generate the form html is controlled by a server side feature toggle (not really import to this question).

For the form, the only difference now is I'm not in a ng-repeat loop and instead I'm doing a ng-include multiple times in a more well defined layout.

The problem I'm having is the values being passed into each ng-include elements only get the ng-init values of the last call on the page, see example below..

{{fieldGroup.name}}

            {{field.field_label}}

    Adjustment

    Total

The old logic generates what you'd expect, but the new logic generates the following. Notice how both fields have the id input_total and other attributes/values of the final call to the template on the page.

    Adjustment

            <input type="text" class="form-control boldInput ng-empty ng-touched" id="input_total" ng-class="" ng-model="$ctrl.contract[field.name]" ng-disabled="field.disabled">

            blah blah blah

    Total

            <input type="text" class="form-control boldInput ng-empty ng-touched" id="input_total" ng-class="" ng-model="$ctrl.contract[field.name]" ng-disabled="field.disabled">

            blah blah blah

I feel like ng-init is not what I should be using to pass-in values for field to the templates in the new form logic, but Uncle Google is failing me.

What should I be using instead of ng-init or how does the scope(?) change inside an ng-repeat versus multiple calls to the templates?


来源: stackexchange

问:
compodoc: command not found
I installed the documentation tool "Compodoc" in my Angular application. First, I installed the tool globally and in my project

```<code>npm install -g @compodoc/compodoc
npm install --save-dev @compodoc/compodoc
</code>```

I added the command to my package.json file in the "scripts" area with the following line

```<code>"compodoc": "./node_modules/.bin/compodoc -p src/tsconfig.app.json"
</code>```

And it generated me the entire documentation files with this command :

```<code>npm run compodoc
</code>```

Everything went good until I tried to run the command compodoc -s to see the documentation in my browser.

```<code>compodoc: command not found
</code>```

答:
Adding this for Angular 9 users:

tell it to create the documentation elsewhere so that 'ng serve' doesn't get confused by the changes caused by the documentation folder if you are using the 'w' folder

Add this package. json then you can run 'npm run compodoc'.
Also, In Angular 9, now I see that I have to specify what folder to watch as well - '-w' means watch the source folder.

"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"compodoc": "./node_modules/.bin/compodoc -p tsconfig.json -w ./src -s --output ../Path To where you want the documentation/documentation --silent"
},

ContentLicense: CC BY-SA 3.0

Title: compodoc: command not found

Body:
I installed the documentation tool "Compodoc" in my Angular application. First, I installed the tool globally and in my project

npm install -g @compodoc/compodoc
npm install --save-dev @compodoc/compodoc

I added the command to my package.json file in the "scripts" area with the following line

"compodoc": "./node_modules/.bin/compodoc -p src/tsconfig.app.json"

And it generated me the entire documentation files with this command :

npm run compodoc

Everything went good until I tried to run the command compodoc -s to see the documentation in my browser.

compodoc: command not found

ContentLicense: CC BY-SA 4.0


问:
Lua wireshark dissector extract timestamp in OLE automation format
ref: OLE Automation date in lua

I'm writing a simple UDP dissector in LUA to decode packets that contain a timestamp that was encoded as an OLE automation date. The encoding results in an 8-byte data pattern:

```<code>C2 F5 4F 12 FD 6B E5 40
</code>```

which decodes as 43871.90848539352 = '2/10/2020 9:48:13 PM'. In C# .NET this is via the DateTime.ToOADate() method (which works fine).

Here is my simplified dissector, which 'decodes' an 8-byte message that consists only of the timestamp:

```<code>local logger_proto = Proto("logger", "LOGGER")
local logger_hdr={
    atime = ProtoField.absolute_time("test.atime","test atime",base.UTC),
    rtime = ProtoField.relative_time("test.rtime","test rtime",base.UTC),
}
logger_proto.fields=logger_hdr

function logger_proto.init() end

function logger_proto.dissector(tvbuf, pktinfo, root)
    root:add(logger_hdr.atime,tvbuf:range(0,8))
    root:add(logger_hdr.atime,tvbuf:range(8,8))
end
</code>```

In the test packet I send the timestamp twice, the second time is with the bytes in reverse order to test for endian issues (the 'grasping at straws' approach). The packet data is:

```<code>C2 F5 4F 12 FD 6B E5 40 40 E5 6B FD 12 4F F5 C2
</code>```

the two retrieved timestamps are

```<code>Aug 25, 2073 03:14:26.-4360608 UTC
Jul  2, 2004 14:06:53.307230146 UTC
</code>```

the 'correct' timestamp should be

```<code>Feb 10, 2020 21:48:13 UTC
</code>```

It looks like ProtoField.absolute_time with base.UTC is not quite what I am looking for. So my questions are

Is there a ProtoField option to extract this timestamp correctly, in a format that excludes fractional seconds?

If not, how would I extract the date/time bytewise and make calculations to format the correct date by hand?

答:
I had to learn a bit about OLE dates but found relevant information at DateTime.ToOADate Method.  I also used information from the OLE Automation date in lua question as well as from Convert us-timestamp to absolute_time to come up with a possible solution for you.  I doubt it's an optimal one, but it seems to work based on the data provided.  Hopefully it works for you but if not, it should get you closer to a solution.

A long-term solution would be if Wireshark could supply native support for OLE dates, and for that to happen, I'd recommend filing a Wireshark enhancement bug report requesting just such a thing.

A possible solution (with some extra stuff for illustrative purposes):

```
local p_logger = Proto("logger", "LOGGER")
local logger_hdr = {
    -- Only the oletime_abs field is useful; the rest just help illustrate things
    -- and helped me during debugging.  Remove/rename as you see fit.

    oletime = ProtoField.double("logger.oletime", "OLE time"),

    -- Note: .int64 doesn't work so just using .int32
    oletime_days = ProtoField.int32("logger.oletime.days", "Days"),
    oletime_partial = ProtoField.double("logger.oletime.partial", "Partial"),
    oletime_abs = ProtoField.absolute_time("logger.oleabstime", "OLE Abs time", base.UTC)
}
p_logger.fields = logger_hdr

function p_logger.dissector(tvbuf, pinfo, tree)
    local logger_tree = tree:add(p_logger, tvbuf(0,-1))
    local OLE_DIFF_TO_UNIX = 25569
    local SECS_PER_DAY = 86400
    local oletime = tvbuf:range(0, 8):le_float() - OLE_DIFF_TO_UNIX
    local oletime_days = math.floor(oletime)
    local oletime_partial = (oletime - oletime_days) * SECS_PER_DAY
    local secs = oletime_days * SECS_PER_DAY + math.floor(oletime_partial)
    local nstime = NSTime.new(secs, 0)

    pinfo.cols.protocol:set("LOGGER")
    logger_tree:add(logger_hdr.oletime, tvbuf:range(0, 8), oletime)
    logger_tree:add(logger_hdr.oletime_days, tvbuf:range(0, 8), oletime_days)
    logger_tree:add(logger_hdr.oletime_partial, tvbuf:range(0, 8), oletime_partial)
    logger_tree:add(logger_hdr.oletime_abs, tvbuf:range(0, 8), nstime)
end

-- Register dissector (this particular registration is just for my testing)
local udp_table = DissectorTable.get("udp.port")
udp_table:add(33333, p_logger)
```

I'm sure this can be cleaned up/optimized, but I leave that as an exercise to the reader.  Tested with the following hand-crafted packet:

```
0000   00 0e b6 00 00 02 00 0e b6 00 00 01 08 00 45 00   ..............E.
0010   00 37 00 00 40 00 40 11 b5 ea c0 00 02 65 c0 00   .7..@.@......e..
0020   02 66 82 35 82 35 00 23 e8 54 c2 f5 4f 12 fd 6b   .f.5.5.#.T..O..k
0030   e5 40 40 e5 6b fd 12 4f f5 c2 00 00 00 00 00 00   .@@.k..O........
0040   00 00 00 00 00                                    .....
```

... and you should get the following decode of the "Logger" OLE date:

```
LOGGER
    OLE time: 18302.9084853935
    Days: 18302
    Partial: 78493.1380001362
    OLE Abs time: Feb 10, 2020 21:48:13.000000000 UTC
```

You can use text2pcap to convert it to a pcap file for testing.  For example: text2pcap -a logger.txt logger.pcap ... where logger.txt is a text file containing the raw packet bytes pasted above.

Body:
ref: OLE Automation date in lua

I'm writing a simple UDP dissector in LUA to decode packets that contain a timestamp that was encoded as an OLE automation date. The encoding results in an 8-byte data pattern:

C2 F5 4F 12 FD 6B E5 40

which decodes as 43871.90848539352 = '2/10/2020 9:48:13 PM'. In C# .NET this is via the DateTime.ToOADate() method (which works fine).

Here is my simplified dissector, which 'decodes' an 8-byte message that consists only of the timestamp:

local logger_proto = Proto("logger", "LOGGER")
local logger_hdr={
    atime = ProtoField.absolute_time("test.atime","test atime",base.UTC),
    rtime = ProtoField.relative_time("test.rtime","test rtime",base.UTC),
}
logger_proto.fields=logger_hdr

function logger_proto.init() end

function logger_proto.dissector(tvbuf, pktinfo, root)
    root:add(logger_hdr.atime,tvbuf:range(0,8))
    root:add(logger_hdr.atime,tvbuf:range(8,8))
end

In the test packet I send the timestamp twice, the second time is with the bytes in reverse order to test for endian issues (the 'grasping at straws' approach). The packet data is:

C2 F5 4F 12 FD 6B E5 40 40 E5 6B FD 12 4F F5 C2

the two retrieved timestamps are

Aug 25, 2073 03:14:26.-4360608 UTC
Jul  2, 2004 14:06:53.307230146 UTC

the 'correct' timestamp should be

Feb 10, 2020 21:48:13 UTC

It looks like ProtoField.absolute_time with base.UTC is not quite what I am looking for. So my questions are

Is there a ProtoField option to extract this timestamp correctly, in a format that excludes fractional seconds?

If not, how would I extract the date/time bytewise and make calculations to format the correct date by hand?

Body:
I had to learn a bit about OLE dates but found relevant information at DateTime.ToOADate Method.  I also used information from the OLE Automation date in lua question as well as from Convert us-timestamp to absolute_time to come up with a possible solution for you.  I doubt it's an optimal one, but it seems to work based on the data provided.  Hopefully it works for you but if not, it should get you closer to a solution.

A long-term solution would be if Wireshark could supply native support for OLE dates, and for that to happen, I'd recommend filing a Wireshark enhancement bug report requesting just such a thing.

A possible solution (with some extra stuff for illustrative purposes):

local p_logger = Proto("logger", "LOGGER")
local logger_hdr = {
    -- Only the oletime_abs field is useful; the rest just help illustrate things
    -- and helped me during debugging.  Remove/rename as you see fit.

    oletime = ProtoField.double("logger.oletime", "OLE time"),

    -- Note: .int64 doesn't work so just using .int32
    oletime_days = ProtoField.int32("logger.oletime.days", "Days"),
    oletime_partial = ProtoField.double("logger.oletime.partial", "Partial"),
    oletime_abs = ProtoField.absolute_time("logger.oleabstime", "OLE Abs time", base.UTC)
}
p_logger.fields = logger_hdr

function p_logger.dissector(tvbuf, pinfo, tree)
    local logger_tree = tree:add(p_logger, tvbuf(0,-1))
    local OLE_DIFF_TO_UNIX = 25569
    local SECS_PER_DAY = 86400
    local oletime = tvbuf:range(0, 8):le_float() - OLE_DIFF_TO_UNIX
    local oletime_days = math.floor(oletime)
    local oletime_partial = (oletime - oletime_days) * SECS_PER_DAY
    local secs = oletime_days * SECS_PER_DAY + math.floor(oletime_partial)
    local nstime = NSTime.new(secs, 0)

    pinfo.cols.protocol:set("LOGGER")
    logger_tree:add(logger_hdr.oletime, tvbuf:range(0, 8), oletime)
    logger_tree:add(logger_hdr.oletime_days, tvbuf:range(0, 8), oletime_days)
    logger_tree:add(logger_hdr.oletime_partial, tvbuf:range(0, 8), oletime_partial)
    logger_tree:add(logger_hdr.oletime_abs, tvbuf:range(0, 8), nstime)
end

-- Register dissector (this particular registration is just for my testing)
local udp_table = DissectorTable.get("udp.port")
udp_table:add(33333, p_logger)

I'm sure this can be cleaned up/optimized, but I leave that as an exercise to the reader.  Tested with the following hand-crafted packet:

0000   00 0e b6 00 00 02 00 0e b6 00 00 01 08 00 45 00   ..............E.
0010   00 37 00 00 40 00 40 11 b5 ea c0 00 02 65 c0 00   .7..@.@......e..
0020   02 66 82 35 82 35 00 23 e8 54 c2 f5 4f 12 fd 6b   .f.5.5.#.T..O..k
0030   e5 40 40 e5 6b fd 12 4f f5 c2 00 00 00 00 00 00   .@@.k..O........
0040   00 00 00 00 00                                    .....

... and you should get the following decode of the "Logger" OLE date:

LOGGER
    OLE time: 18302.9084853935
    Days: 18302
    Partial: 78493.1380001362
    OLE Abs time: Feb 10, 2020 21:48:13.000000000 UTC

You can use text2pcap to convert it to a pcap file for testing.  For example: text2pcap -a logger.txt logger.pcap ... where logger.txt is a text file containing the raw packet bytes pasted above.


问:
ASP.NET MVC: Model in strongly typed view not populating
I am brand spanking new to ASP.NET MVC and I'm working through a tutorial to get the basics.  The tutorial is in C# and I'm converting it to VB to stay consistent with some related projects.  I have to assume that I'm missing something in that conversion but can't figure out what it could be.

I have the following class:

```<code>Public Class GuestResponse
    Public Name As String
    Public Email As String
    Public Phone As String
    Public WillAttend As Boolean?
End Class
</code>```

and a strongly-typed view related to that class:

```<code>@ModelType PartyInvites.GuestResponse

@Code
    Layout = Nothing
End Code

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>RsvpForm</title>
</head>
<body>
    @Using Html.BeginForm
        @<p>Your name: @Html.TextBoxFor(Of String)(Function(x) x.Name)</p>
        @<p>Your email: @Html.TextBoxFor(Of String)(Function(x) x.Email)</p>
        @<p>Your phone: @Html.TextBoxFor(Of String)(Function(x) x.Phone)</p>
        @<p>
            Will you attend?
            @Html.DropDownListFor(Of Boolean?)(Function(x) x.WillAttend,
                                                        New SelectListItem() {New SelectListItem With {.Text = "Yes, I'll be there", .Value = Boolean.TrueString},
                                                        New SelectListItem With {.Text = "No, I can't come", .Value = Boolean.FalseString}}, "Choose an option")
        </p>
        @<input type="submit" value="Submit RSVP" />
    End Using
</body>
</html>
</code>```

My controller has a simple action method that takes that class and responds with another view:

```<code><HttpPost>
Function RsvpForm(g As GuestResponse) As ViewResult
    'TODO: Email response to the party organizer
    Return View("Thanks", g)
End Function
</code>```

Unfortunately, the form data from the post request isn't being populated in my GuestResponse class.  If I insert a breakpoint in that action method, all the GuestResponse properties are empty.  At the same time, the Request.Form values look as expected - they're just not filling in the GuestResponse object.

I'm sure it's something small I'm missing.  Any help is appreciated.

答: Try adding a <FromForm> attribute to the g parameter.

Body:
I am brand spanking new to ASP.NET MVC and I'm working through a tutorial to get the basics.  The tutorial is in C# and I'm converting it to VB to stay consistent with some related projects.  I have to assume that I'm missing something in that conversion but can't figure out what it could be.

I have the following class:

Public Class GuestResponse
    Public Name As String
    Public Email As String
    Public Phone As String
    Public WillAttend As Boolean?
End Class

and a strongly-typed view related to that class:

@ModelType PartyInvites.GuestResponse

@Code
    Layout = Nothing
End Code

<!DOCTYPE html>

    <meta name="viewport" content="width=device-width" />
    <title>RsvpForm</title>

    @Using Html.BeginForm
        @
Your name: @Html.TextBoxFor(Of String)(Function(x) x.Name)

        @
Your email: @Html.TextBoxFor(Of String)(Function(x) x.Email)

        @
Your phone: @Html.TextBoxFor(Of String)(Function(x) x.Phone)

        @

            Will you attend?
            @Html.DropDownListFor(Of Boolean?)(Function(x) x.WillAttend,
                                                        New SelectListItem() {New SelectListItem With {.Text = "Yes, I'll be there", .Value = Boolean.TrueString},
                                                        New SelectListItem With {.Text = "No, I can't come", .Value = Boolean.FalseString}}, "Choose an option")

        @<input type="submit" value="Submit RSVP" />
    End Using

My controller has a simple action method that takes that class and responds with another view:

<HttpPost>
Function RsvpForm(g As GuestResponse) As ViewResult
    'TODO: Email response to the party organizer
    Return View("Thanks", g)
End Function

Unfortunately, the form data from the post request isn't being populated in my GuestResponse class.  If I insert a breakpoint in that action method, all the GuestResponse properties are empty.  At the same time, the Request.Form values look as expected - they're just not filling in the GuestResponse object.

I'm sure it's something small I'm missing.  Any help is appreciated.


问:
Is it possible to wait for all actions in the ofType operator to be called before calling next?
I have an array of redux actions which when ALL have been called I want to call another action in my epic. The actions in the array are changeable, dynamic. What I'm hoping to find would be the equivalent of the ofType operator working like this:

ofType(FETCH_USER_PROFILE_SUCCESS && FETCH_USER_PREFERENCES_SUCCESS)

When both actions have been called, another is called further down the pipe. Of course the ofType operator doesn't work like this. It only needs one of the actions to be called to continue.

I have read that combineLatest might be the solution here but I've had no luck. Below is what I imagine the solution could look like but obviously this doesn't work for me. Any suggestions would be appreciated.

```<code>const actions = ['FETCH_USER_PROFILE_SUCCESS', 'FETCH_USER_PREFERENCES_SUCCESS'];

const asTypes = actions.map((action) => ofType(action);

const userEpic = (action$, state$) =>
  action$.pipe(
    combineLatest(asTypes);
    mergeMap(() =>
      of({
        type: 'SET_USER_READY'
      })
    )
  );
</code>```

Following on from replies below:

Just to clear what I meant by dynamic. The array of actions might include more actions depending on a user's profile (e.g. 'FETCH_USER_POSTS_SUCCESS'), essentially an unknown number of actions depending on the user.

So, is possible to generate this dynamically:

zip(
    action$.pipe(ofType('FETCH_USER_PROFILE_SUCCESS')),
    action$.pipe(ofType('FETCH_USER_PREFERENCES_SUCCESS')),
  )

```<code>const actions = ['FETCH_USER_PROFILE_SUCCESS', 'FETCH_USER_PREFERENCES_SUCCESS', unknown number of more actions];

const actions = dynamic.forEach((action) => action$.pipe(ofType(action))

zip(
    actions
  )
</code>```

答:
why not making one general action like executeAllActions and inside this action payload you pass an array which contain all the references for all the actions you want like

executeAllActions = {
    type: 'exectueAllActions',
    actionsList: [ fetchCategories, fetchProducts, ...],
}
```

<p>then you listen for this action</p>

```this.actions$.pipe(
   ofType(executeAllActions),
   concatMap(action => [ ...actions.actionsList ])
)
```

where we used concatMap to return  a list of actoins that will all be executed.

I wish I can try this idea now, but I think it somehow possible.
If it works for you please let me know.

Body:
I have an array of redux actions which when ALL have been called I want to call another action in my epic. The actions in the array are changeable, dynamic. What I'm hoping to find would be the equivalent of the ofType operator working like this:

ofType(FETCH_USER_PROFILE_SUCCESS && FETCH_USER_PREFERENCES_SUCCESS)

When both actions have been called, another is called further down the pipe. Of course the ofType operator doesn't work like this. It only needs one of the actions to be called to continue.

I have read that combineLatest might be the solution here but I've had no luck. Below is what I imagine the solution could look like but obviously this doesn't work for me. Any suggestions would be appreciated.

const actions = ['FETCH_USER_PROFILE_SUCCESS', 'FETCH_USER_PREFERENCES_SUCCESS'];

const asTypes = actions.map((action) => ofType(action);

const userEpic = (action$, state$) =>
  action$.pipe(
    combineLatest(asTypes);
    mergeMap(() =>
      of({
        type: 'SET_USER_READY'
      })
    )
  );

Following on from replies below:

Just to clear what I meant by dynamic. The array of actions might include more actions depending on a user's profile (e.g. 'FETCH_USER_POSTS_SUCCESS'), essentially an unknown number of actions depending on the user.

So, is possible to generate this dynamically:

zip(
    action$.pipe(ofType('FETCH_USER_PROFILE_SUCCESS')),
    action$.pipe(ofType('FETCH_USER_PREFERENCES_SUCCESS')),
  )

const actions = ['FETCH_USER_PROFILE_SUCCESS', 'FETCH_USER_PREFERENCES_SUCCESS', unknown number of more actions];

const actions = dynamic.forEach((action) => action$.pipe(ofType(action))

zip(
    actions
  )

Body:
why not making one general action like executeAllActions and inside this action payload you pass an array which contain all the references for all the actions you want like

executeAllActions = {
    type: 'exectueAllActions',
    actionsList: [ fetchCategories, fetchProducts, ...],
}

then you listen for this action

this.actions$.pipe(
   ofType(executeAllActions),
   concatMap(action => [ ...actions.actionsList ])
)

where we used concatMap to return  a list of actoins that will all be executed.

I wish I can try this idea now, but I think it somehow possible.
If it works for you please let me know.


问:
Searching triplets in two arrays
Given two arrays a and b of size n. I have to choose one element from a and two elements from b such that. a[i] * a[i] = b[j] * b[k].

I am able to find BruteForce in O(n^2 log(n)) traversing both the arrays and binary searching the value. But dont know how to improve it even more.

How do I count all these number where elements range from 1 <= a[i] <= 10^6 and 1 <= n <= 10^6.

答:
Well, I can think in a O(n²) solution.

```<code>unordered_multiset S = {}
for each element B in b {
    S = S ∪ B
}
</code>```

First of all, we store all elements of b in a unordered_multiset. Such structure can find elements in O(1) time and if you add 2 or more equal elements, it also knows.

```<code>for each element B in b {
    for each element A in a {
        if( A² % B != 0 ) continue;                            //making sure it's divisible
        let occurrencies = number_of_occurrencies(A² / B, S);
        if( occurrencies > 0 ) {                               //if (A² / B) is in S
            if( A == B and ocurrencies > 1 ) {
                //your answer is A, B and B
            }
            else if ( A != B ) {
                //your answer is A, B and A² / B
            }
        }
    }
}
</code>```

Here you loop over both arrays. The main goal is to check, for each element in b, which elements it must be multiplied for in order to be equal to some element of a squared. The, it checks if the element B needs is already in S.

There is a little trick in that. If A = 30 and B = 30, it means that you want to have another 30 in b who's not B. That's the reason of the multiset. If there is only one 30 in the whole set, you know that you are trying to match B with itself, and you can't do that, hence you have to have at least 2 elements valued 30 in b.

Title: Searching triplets in two arrays

Body:
Well, I can think in a O(n²) solution.

unordered_multiset S = {}
for each element B in b {
    S = S ∪ B
}

First of all, we store all elements of b in a unordered_multiset. Such structure can find elements in O(1) time and if you add 2 or more equal elements, it also knows.

for each element B in b {
    for each element A in a {
        if( A² % B != 0 ) continue;                            //making sure it's divisible
        let occurrencies = number_of_occurrencies(A² / B, S);
        if( occurrencies > 0 ) {                               //if (A² / B) is in S
            if( A == B and ocurrencies > 1 ) {
                //your answer is A, B and B
            }
            else if ( A != B ) {
                //your answer is A, B and A² / B
            }
        }
    }
}

Here you loop over both arrays. The main goal is to check, for each element in b, which elements it must be multiplied for in order to be equal to some element of a squared. The, it checks if the element B needs is already in S.

There is a little trick in that. If A = 30 and B = 30, it means that you want to have another 30 in b who's not B. That's the reason of the multiset. If there is only one 30 in the whole set, you know that you are trying to match B with itself, and you can't do that, hence you have to have at least 2 elements valued 30 in b.


问:
Rails routing error: No route matches [POST] "/students/1"
I'm getting a routing error: No route matches [POST] "/students/1" that I can't figure out.  Here are the details.

view code:

```<code><% @students.each do |student| %>
.
.
    <td><%= link_to 'Show', student %></td>
    <td><%= link_to 'Edit', edit_student_path(student) %></td>
    <td><%= link_to 'Select Subjects', select_path(student) %></td>  # error occurs here
</code>```

In my students controller:

```<code>def select
  .
  .
end
</code>```

routes.rb:
    HomeSchool::Application.routes.draw do

```<code>  resources :notes

  resources :assignments

  resources :subjects do
    resources :assignments, :only => [:create, :index, :new]
  end

  resources :students

  resources :resources

  match "students/:id/select" => "students#select", :as => :select

  root :to => 'students#index'

end
</code>```

The output from rake routes is:

```<code>                       GET    /students/:id/select(.:format)                  students/:id#select
                 notes GET    /notes(.:format)                                notes#index
                       POST   /notes(.:format)                                notes#create
              new_note GET    /notes/new(.:format)                            notes#new
             edit_note GET    /notes/:id/edit(.:format)                       notes#edit
                  note GET    /notes/:id(.:format)                            notes#show
                       PUT    /notes/:id(.:format)                            notes#update
                       DELETE /notes/:id(.:format)                            notes#destroy
           assignments GET    /assignments(.:format)                          assignments#index
                       POST   /assignments(.:format)                          assignments#create
        new_assignment GET    /assignments/new(.:format)                      assignments#new
       edit_assignment GET    /assignments/:id/edit(.:format)                 assignments#edit
            assignment GET    /assignments/:id(.:format)                      assignments#show
                       PUT    /assignments/:id(.:format)                      assignments#update
                       DELETE /assignments/:id(.:format)                      assignments#destroy
   subject_assignments GET    /subjects/:subject_id/assignments(.:format)     assignments#index
                       POST   /subjects/:subject_id/assignments(.:format)     assignments#create
new_subject_assignment GET    /subjects/:subject_id/assignments/new(.:format) assignments#new
              subjects GET    /subjects(.:format)                             subjects#index
                       POST   /subjects(.:format)                             subjects#create
           new_subject GET    /subjects/new(.:format)                         subjects#new
          edit_subject GET    /subjects/:id/edit(.:format)                    subjects#edit
               subject GET    /subjects/:id(.:format)                         subjects#show
                       PUT    /subjects/:id(.:format)                         subjects#update
                       DELETE /subjects/:id(.:format)                         subjects#destroy
              students GET    /students(.:format)                             students#index
                       POST   /students(.:format)                             students#create
           new_student GET    /students/new(.:format)                         students#new
          edit_student GET    /students/:id/edit(.:format)                    students#edit
               student GET    /students/:id(.:format)                         students#show
                       PUT    /students/:id(.:format)                         students#update
                       DELETE /students/:id(.:format)                         students#destroy
             resources GET    /resources(.:format)                            resources#index
                       POST   /resources(.:format)                            resources#create
          new_resource GET    /resources/new(.:format)                        resources#new
         edit_resource GET    /resources/:id/edit(.:format)                   resources#edit
              resource GET    /resources/:id(.:format)                        resources#show
                       PUT    /resources/:id(.:format)                        resources#update
                       DELETE /resources/:id(.:format)                        resources#destroy
                select        /students/:id/select(.:format)                  students#select
                  root        /                                               students#index
</code>```

Any suggestions?  I'm having a really hard time grasping exactly how routing in rails is supposed to work and I have yet to find any kind of treatise on it but I'm pretty sure that having no method listed for my select route is at least part of my problem.

Thanks,

Lon

答:
This happens because of your routes.rb file. It doesn't have a callback for post method in "/students/new"

To correct this.
Go to routes.rb and add post 'students/new' to: 'students#new' before end.

and check rails routes. you will find a routing path there for the post.

Body:
I'm getting a routing error: No route matches [POST] "/students/1" that I can't figure out.  Here are the details.

view code:

<% @students.each do |student| %>
.
.
    <%= link_to 'Show', student %>
    <%= link_to 'Edit', edit_student_path(student) %>
    <%= link_to 'Select Subjects', select_path(student) %>	  # error occurs here

In my students controller:

def select
  .
  .
end

routes.rb:
    HomeSchool::Application.routes.draw do

  resources :notes

  resources :assignments

  resources :subjects do
    resources :assignments, :only => [:create, :index, :new]
  end

  resources :students

  resources :resources

  match "students/:id/select" => "students#select", :as => :select

  root :to => 'students#index'

end

The output from rake routes is:

                       GET    /students/:id/select(.:format)                  students/:id#select
                 notes GET    /notes(.:format)                                notes#index
                       POST   /notes(.:format)                                notes#create
              new_note GET    /notes/new(.:format)                            notes#new
             edit_note GET    /notes/:id/edit(.:format)                       notes#edit
                  note GET    /notes/:id(.:format)                            notes#show
                       PUT    /notes/:id(.:format)                            notes#update
                       DELETE /notes/:id(.:format)                            notes#destroy
           assignments GET    /assignments(.:format)                          assignments#index
                       POST   /assignments(.:format)                          assignments#create
        new_assignment GET    /assignments/new(.:format)                      assignments#new
       edit_assignment GET    /assignments/:id/edit(.:format)                 assignments#edit
            assignment GET    /assignments/:id(.:format)                      assignments#show
                       PUT    /assignments/:id(.:format)                      assignments#update
                       DELETE /assignments/:id(.:format)                      assignments#destroy
   subject_assignments GET    /subjects/:subject_id/assignments(.:format)     assignments#index
                       POST   /subjects/:subject_id/assignments(.:format)     assignments#create
new_subject_assignment GET    /subjects/:subject_id/assignments/new(.:format) assignments#new
              subjects GET    /subjects(.:format)                             subjects#index
                       POST   /subjects(.:format)                             subjects#create
           new_subject GET    /subjects/new(.:format)                         subjects#new
          edit_subject GET    /subjects/:id/edit(.:format)                    subjects#edit
               subject GET    /subjects/:id(.:format)                         subjects#show
                       PUT    /subjects/:id(.:format)                         subjects#update
                       DELETE /subjects/:id(.:format)                         subjects#destroy
              students GET    /students(.:format)                             students#index
                       POST   /students(.:format)                             students#create
           new_student GET    /students/new(.:format)                         students#new
          edit_student GET    /students/:id/edit(.:format)                    students#edit
               student GET    /students/:id(.:format)                         students#show
                       PUT    /students/:id(.:format)                         students#update
                       DELETE /students/:id(.:format)                         students#destroy
             resources GET    /resources(.:format)                            resources#index
                       POST   /resources(.:format)                            resources#create
          new_resource GET    /resources/new(.:format)                        resources#new
         edit_resource GET    /resources/:id/edit(.:format)                   resources#edit
              resource GET    /resources/:id(.:format)                        resources#show
                       PUT    /resources/:id(.:format)                        resources#update
                       DELETE /resources/:id(.:format)                        resources#destroy
                select        /students/:id/select(.:format)                  students#select
                  root        /                                               students#index

Any suggestions?  I'm having a really hard time grasping exactly how routing in rails is supposed to work and I have yet to find any kind of treatise on it but I'm pretty sure that having no method listed for my select route is at least part of my problem.

Thanks,

Lon


问:
Map an environment variable in Github Actions
I created a GitHub Actions Job with a strategy matrix that creates a set of environment variables.
One of them is machine_architecture which is either 32 or 64.

In most steps I can use it directly i.e. via ${{ machine_architecture }}.
But some steps requires strings like 'i386' vs 'x86_64'. Is there an easy way in github actions to create a map-object that I can use in expressions like:

```<code>map_object = { 32: "i386", 64: 'x86_64' }
...
${{ map_object[machine_architecture] }}
</code>```

If not, what is the idiomatic way in github actions to solve that problem?

PS: I am aware, that I can set environment variables in steps, but the problem is, that these variables are only available for the following steps (i.e. not for usage in "run-on:" tag)

答:
How about your "map_object" is actually a file mapping machine_architecture values into the values you need, such:

```<code>32=i386
64=x86_64
</code>```

or any other format you want to keep.

Then, your job can define it in a secondary variable as:

```<code>jobs:
  FirstJob:
    name: job 1
    runs-on: .....
    steps:
      - uses: ....
      - name: Define variables
        run: |
          cat $(cat MAP_OBJECT_FILE_NAME) | grep $(cat machine_architecture)= | > MACHINE_ARCHITECTURE_STRING
</code>```

From there on, you would have the MACHINE_ARCHITECTURE_STRING variable available for the jobs you need. You could of course do it much more simple concatenating or whatever, but here you maintain the mapping in your code with the mapping file and is escalable.

Body:
I created a GitHub Actions Job with a strategy matrix that creates a set of environment variables.
One of them is machine_architecture which is either 32 or 64.

In most steps I can use it directly i.e. via ${{ machine_architecture }}.
But some steps requires strings like 'i386' vs 'x86_64'. Is there an easy way in github actions to create a map-object that I can use in expressions like:

map_object = { 32: "i386", 64: 'x86_64' }
...
${{ map_object[machine_architecture] }}

If not, what is the idiomatic way in github actions to solve that problem?

PS: I am aware, that I can set environment variables in steps, but the problem is, that these variables are only available for the following steps (i.e. not for usage in "run-on:" tag)

Body:
How about your "map_object" is actually a file mapping machine_architecture values into the values you need, such:

32=i386
64=x86_64

or any other format you want to keep.

Then, your job can define it in a secondary variable as:

jobs:
  FirstJob:
    name: job 1
    runs-on: .....
    steps:
      - uses: ....
      - name: Define variables
        run: |
          cat $(cat MAP_OBJECT_FILE_NAME) | grep $(cat machine_architecture)= | > MACHINE_ARCHITECTURE_STRING

From there on, you would have the MACHINE_ARCHITECTURE_STRING variable available for the jobs you need. You could of course do it much more simple concatenating or whatever, but here you maintain the mapping in your code with the mapping file and is escalable.


问:
Remove last char in a string for each row in pandas df
I have a pandas dataframe with column keys, I need to remove the last character from each string.

```<code>id       keys
123      "https://www.cosmopolitan.com/entertainment/tv/a46533/"
124      "https://www.bazaar.com/entertainment/tv/a46533/"
</code>```

Currently, I am trying to create a function that would return a clean string and I would apply the function to df later. I tried the following:

```<code>url_test = "https://www.cosmopolitan.com/entertainment/tv/"

def clean_string(url):
    for string in url:
        new_string = string[:-1]
        return new_string
clean_string(url_test)
</code>```

It returns an empty string. And I want it to return "url_test = "https://www.cosmopolitan.com/entertainment/tv"

答:
If your column key contains all values of str type, and you would like to apply (or rather, map) the function to the column, you could simply use rstrip (or just strip) without defining a function.

Suppose your given pandas dataframe is named as df, try:

new_keys = df['keys'].str.rstrip('/')
```

The new_keys is a pandas series.

Body:
I have a pandas dataframe with column keys, I need to remove the last character from each string.

id       keys
123      "https://www.cosmopolitan.com/entertainment/tv/a46533/"
124      "https://www.bazaar.com/entertainment/tv/a46533/"

Currently, I am trying to create a function that would return a clean string and I would apply the function to df later. I tried the following:

url_test = "https://www.cosmopolitan.com/entertainment/tv/"

def clean_string(url):
    for string in url:
        new_string = string[:-1]
        return new_string
clean_string(url_test)

It returns an empty string. And I want it to return "url_test = "https://www.cosmopolitan.com/entertainment/tv"

Body:
If your column key contains all values of str type, and you would like to apply (or rather, map) the function to the column, you could simply use rstrip (or just strip) without defining a function.

Suppose your given pandas dataframe is named as df, try:

new_keys = df['keys'].str.rstrip('/')

The new_keys is a pandas series.


问:
Unable to run app in emulator with API 29 android studio
I have an app run normally in the emulator with API 28. But when I run the app in the emulator with API 29 it shows

It does not only show keeps stopping in the emulator. I tried to install it on mobile and it also shows the same error.

The log shows this error like this:

```<code>2020-02-14 19:48:12.922 20370-20370/? E/stickerappmake: Unknown bits set in runtime_flags: 0x8000
2020-02-14 19:48:15.326 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:15.326 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:15.385 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:15.385 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:17.138 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:17.139 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:17.243 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:17.243 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:19.984 20370-20464/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:19.984 20370-20464/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:20.048 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:20.048 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:20.059 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:20.063 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:22.727 20370-20370/com.testdev.appname E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.testdev.appname, PID: 20370
    java.lang.NullPointerException: Attempt to get length of null array
        at com.testdev.appname.activities.CreateFragment.loadStickersCreated(CreateFragment.java:52)
        at com.testdev.appname.activities.CreateFragment.onCreateView(CreateFragment.java:88)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:2439)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
        at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
        at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
        at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
        at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
        at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
        at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
        at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:620)
        at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1425)
        at android.app.Activity.performStart(Activity.java:7825)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
</code>```

I see there some problems with the java code in CreateFragment.java. And the java code is like below:
The CreateFragment.java code:

package com.devname.appname.activities;

```<code>import android.app.Activity;
import android.app.AlertDialog;
import android.support.v4.app.Fragment;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.facebook.drawee.view.SimpleDraweeView;
import com.devname.appname.helpers.Admob;
import com.sangcomz.fishbun.FishBun;
import com.sangcomz.fishbun.adapter.image.impl.GlideAdapter;
import com.sangcomz.fishbun.define.Define;
import com.devname.appname.R;
import com.devname.appname.backgroundRemover.CutOut;
import com.devname.appname.helpers.Constants;
import com.devname.appname.utils.FileUtils;
import com.devname.appname.utils.StickerPacksManager;

import java.io.File;
import java.util.ArrayList;

public class CreateFragment extends Fragment {
    ImagesGridAdapter imagesGridAdapter;
    View view;

    public CreateFragment() {
        // Required empty public constructor
    }

    public static ArrayList<Uri> loadStickersCreated() {
        String directoryPath = Constants.STICKERS_CREATED_DIRECTORY_PATH;
        File directory = new File(directoryPath);
        ArrayList<Uri> images = new ArrayList<>();
        if (directory.exists()) {
            File[] stickersImages = directory.listFiles();
            for (File f : stickersImages) {
                if (f.isFile() && (f.getName().contains(".png") || f.getName().contains(".PNG"))) {
                    images.add(Uri.fromFile((f)));
                }
            }
        } else {
            directory.mkdir();
        }
       // verifyStickersCount();
        return images;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        view = inflater.inflate(R.layout.fragment_create, container, false);
        Admob.createLoadBanner(getContext(), view);
        view.findViewById(R.id.create_sticker).setOnClickListener(v -> FishBun.with(getActivity())
                .setImageAdapter(new GlideAdapter())
                .setMaxCount(1)
                .exceptGif(true)
                .setMinCount(1)
                .setActionBarColor(getResources().getColor(R.color.colorPrimaryDark), getResources().getColor(R.color.colorPrimary), false)
                .setActionBarTitleColor(Color.parseColor("#ffffff"))
                .startAlbum());

        RecyclerView gridview = view.findViewById(R.id.stickers_created_grid);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(view.getContext(), 3);
        gridview.setLayoutManager(gridLayoutManager);
        imagesGridAdapter = new ImagesGridAdapter(view.getContext(), loadStickersCreated());
        gridview.setAdapter(imagesGridAdapter);
        verifyStickersCount();
        return view;
    }

    public void verifyStickersCount() {
        View linearLayout = view.findViewById(R.id.no_stickers_icon);
        if (imagesGridAdapter == null || imagesGridAdapter.getItemCount() == 0) {
            linearLayout.setVisibility(View.VISIBLE);
        } else {
            linearLayout.setVisibility(View.GONE);
        }
    }

    public static void addImageToGallery(final String filePath, final Context context) {

        ContentValues values = new ContentValues();

        values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        values.put(MediaStore.MediaColumns.DATA, filePath);

        context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d("TESTTTTTT",requestCode+"");
        if (requestCode == CutOut.CUTOUT_ACTIVITY_REQUEST_CODE) {
            Log.d("TESTTTTTT :::::",requestCode+"");
            switch (resultCode) {
                case Activity.RESULT_OK:
                    String imagePath_intent = data.getStringExtra("imagePath");
                    Uri imageUri = Uri.fromFile(new File(imagePath_intent));

                    Log.d("TESTTTTTT ::::: He",imageUri+"");
                    String stickerName = FileUtils.generateRandomIdentifier();
                    Uri imagePath = Uri.parse(Constants.STICKERS_CREATED_DIRECTORY_PATH + stickerName + ".PNG");
                    StickerPacksManager.createStickerImageFile(imageUri, imagePath, getActivity(), Bitmap.CompressFormat.PNG);
                    addImageToGallery(imagePath.getPath(), getActivity());
                    imagesGridAdapter.uries = loadStickersCreated();
                    imagesGridAdapter.notifyDataSetChanged();
                    Toast.makeText(getActivity(), "Sticker created", Toast.LENGTH_LONG).show();
                    verifyStickersCount();
                    break;
                case CutOut.CUTOUT_ACTIVITY_RESULT_ERROR_CODE:
                    Exception ex = CutOut.getError(data);
                    Log.d("TESTTTTTT :::::",ex+"::DDD");
                    break;
                default:
                    System.out.print("User cancelled the CutOut screen");
            }
        } else if (requestCode == Define.ALBUM_REQUEST_CODE) {
            ArrayList<Uri> uries;
            if (resultCode == Activity.RESULT_OK) {
                uries = data.getParcelableArrayListExtra(Define.INTENT_PATH);
                CutOut.activity().src(uries.get(0)).intro().start(getActivity());
            }
        }
    }

    public class ImagesGridAdapter extends RecyclerView.Adapter<ImageViewHolder> {
        public ArrayList<Uri> uries = new ArrayList<>();
        Context context;

        public ImagesGridAdapter(Context context, ArrayList<Uri> uries) {
            this.uries = uries;
            this.context = context;
        }

        @NonNull
        @Override
        public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            final Context context = viewGroup.getContext();
            final LayoutInflater layoutInflater = LayoutInflater.from(context);
            final View view = layoutInflater.inflate(R.layout.sticker_created_item, viewGroup, false);
            return new ImageViewHolder(view);
        }

        @Override
        public void onBindViewHolder(@NonNull ImageViewHolder imageAdapter, int index) {
            imageAdapter.imageView.setImageURI(uries.get(index));
            imageAdapter.imageView.setPadding(8, 8, 8, 8);
            imageAdapter.imageView.setOnLongClickListener(v -> {
                PopupMenu popupMenu = new PopupMenu(context, imageAdapter.imageView);
                popupMenu.inflate(R.menu.sticker_menu);
                popupMenu.setOnMenuItemClickListener(item -> {
                    switch (item.getItemId()) {
                     /*  case R.id.add_to_exist_stickerpack:
                            addToStickerPack(index);
                            break;*/
                        case R.id.delete_sticker:
                            this.deleteSticker(index);
                            break;
                        default:
                            break;
                    }
                    return false;
                });
                popupMenu.show();
                return false;
            });
        }

        void deleteSticker(int index) {
            new AlertDialog.Builder(context)
                    .setTitle("Deleting")
                    .setMessage("Are you sure you want to delete this sticker?")
                    .setPositiveButton("Yes", (dialog, which) -> {
                        Uri uri = uries.get(index);
                        FileUtils.deleteFile(uri.getPath(),context);
                        uries.remove(index);
                        notifyItemRemoved(index);
                        notifyDataSetChanged();
                        Toast.makeText(context, "Deleted", Toast.LENGTH_SHORT).show();
                        verifyStickersCount();
                    })
                    .setNegativeButton("No", null)
                    .show();
        }

         void addToStickerPack(int index) {
            Intent intent = new Intent(context, AddToStickerPackActivity.class);
            intent.setData(uries.get(index));
            startActivity(intent);
        }

        @Override
        public int getItemCount() {
            return uries.size();
        }
    }

    class ImageViewHolder extends RecyclerView.ViewHolder {
        SimpleDraweeView imageView;

        public ImageViewHolder(@NonNull View itemView) {
            super(itemView);
            this.imageView = itemView.findViewById(R.id.sticker_created_image);
        }

    }
}
</code>```

答:
The problem is in directory path in Constants.STICKERS_CREATED_DIRECTORY_PATH. In Constant.java there some codes like below:

```<code>public final static String STICKERS_CREATED_DIRECTORY_PATH = Environment.getExternalStorageDirectory() + "/WA Stickers/My Created/";
</code>```

then I specify the directory path

```<code>public final static String STICKERS_CREATED_DIRECTORY_PATH = Environment.getExternalStorageDirectory() + "/storage/emulated/0/WA Stickers/My Created/";
</code>```

It works. Thanks for your answers.

Edited:
It works only in emulator. I tried installing in real device but the app force closed.

Edited:
problem solved. I installed the apk with different apk signer from previous apk that is already installed. so everything runs normally with codes above.

Body:
I have an app run normally in the emulator with API 28. But when I run the app in the emulator with API 29 it shows

It does not only show keeps stopping in the emulator. I tried to install it on mobile and it also shows the same error.

The log shows this error like this:

2020-02-14 19:48:12.922 20370-20370/? E/stickerappmake: Unknown bits set in runtime_flags: 0x8000
2020-02-14 19:48:15.326 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:15.326 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:15.385 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:15.385 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:17.138 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:17.139 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:17.243 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:17.243 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:19.984 20370-20464/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:19.984 20370-20464/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:20.048 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:20.048 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:20.059 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:20.063 20370-20454/com.testdev.appname E/eglCodecCommon: glUtilsParamSize: unknow param 0x000088ef
2020-02-14 19:48:22.727 20370-20370/com.testdev.appname E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.testdev.appname, PID: 20370
    java.lang.NullPointerException: Attempt to get length of null array
        at com.testdev.appname.activities.CreateFragment.loadStickersCreated(CreateFragment.java:52)
        at com.testdev.appname.activities.CreateFragment.onCreateView(CreateFragment.java:88)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:2439)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
        at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
        at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
        at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
        at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
        at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
        at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
        at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:620)
        at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1425)
        at android.app.Activity.performStart(Activity.java:7825)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

I see there some problems with the java code in CreateFragment.java. And the java code is like below:
The CreateFragment.java code:

package com.devname.appname.activities;

import android.app.Activity;
import android.app.AlertDialog;
import android.support.v4.app.Fragment;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.facebook.drawee.view.SimpleDraweeView;
import com.devname.appname.helpers.Admob;
import com.sangcomz.fishbun.FishBun;
import com.sangcomz.fishbun.adapter.image.impl.GlideAdapter;
import com.sangcomz.fishbun.define.Define;
import com.devname.appname.R;
import com.devname.appname.backgroundRemover.CutOut;
import com.devname.appname.helpers.Constants;
import com.devname.appname.utils.FileUtils;
import com.devname.appname.utils.StickerPacksManager;

import java.io.File;
import java.util.ArrayList;

public class CreateFragment extends Fragment {
    ImagesGridAdapter imagesGridAdapter;
    View view;

    public CreateFragment() {
        // Required empty public constructor
    }

    public static ArrayList<Uri> loadStickersCreated() {
        String directoryPath = Constants.STICKERS_CREATED_DIRECTORY_PATH;
        File directory = new File(directoryPath);
        ArrayList<Uri> images = new ArrayList<>();
        if (directory.exists()) {
            File[] stickersImages = directory.listFiles();
            for (File f : stickersImages) {
                if (f.isFile() && (f.getName().contains(".png") || f.getName().contains(".PNG"))) {
                    images.add(Uri.fromFile((f)));
                }
            }
        } else {
            directory.mkdir();
        }
       // verifyStickersCount();
        return images;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        view = inflater.inflate(R.layout.fragment_create, container, false);
        Admob.createLoadBanner(getContext(), view);
        view.findViewById(R.id.create_sticker).setOnClickListener(v -> FishBun.with(getActivity())
                .setImageAdapter(new GlideAdapter())
                .setMaxCount(1)
                .exceptGif(true)
                .setMinCount(1)
                .setActionBarColor(getResources().getColor(R.color.colorPrimaryDark), getResources().getColor(R.color.colorPrimary), false)
                .setActionBarTitleColor(Color.parseColor("#ffffff"))
                .startAlbum());

        RecyclerView gridview = view.findViewById(R.id.stickers_created_grid);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(view.getContext(), 3);
        gridview.setLayoutManager(gridLayoutManager);
        imagesGridAdapter = new ImagesGridAdapter(view.getContext(), loadStickersCreated());
        gridview.setAdapter(imagesGridAdapter);
        verifyStickersCount();
        return view;
    }

    public void verifyStickersCount() {
        View linearLayout = view.findViewById(R.id.no_stickers_icon);
        if (imagesGridAdapter == null || imagesGridAdapter.getItemCount() == 0) {
            linearLayout.setVisibility(View.VISIBLE);
        } else {
            linearLayout.setVisibility(View.GONE);
        }
    }

    public static void addImageToGallery(final String filePath, final Context context) {

        ContentValues values = new ContentValues();

        values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        values.put(MediaStore.MediaColumns.DATA, filePath);

        context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d("TESTTTTTT",requestCode+"");
        if (requestCode == CutOut.CUTOUT_ACTIVITY_REQUEST_CODE) {
            Log.d("TESTTTTTT :::::",requestCode+"");
            switch (resultCode) {
                case Activity.RESULT_OK:
                    String imagePath_intent = data.getStringExtra("imagePath");
                    Uri imageUri = Uri.fromFile(new File(imagePath_intent));

                    Log.d("TESTTTTTT ::::: He",imageUri+"");
                    String stickerName = FileUtils.generateRandomIdentifier();
                    Uri imagePath = Uri.parse(Constants.STICKERS_CREATED_DIRECTORY_PATH + stickerName + ".PNG");
                    StickerPacksManager.createStickerImageFile(imageUri, imagePath, getActivity(), Bitmap.CompressFormat.PNG);
                    addImageToGallery(imagePath.getPath(), getActivity());
                    imagesGridAdapter.uries = loadStickersCreated();
                    imagesGridAdapter.notifyDataSetChanged();
                    Toast.makeText(getActivity(), "Sticker created", Toast.LENGTH_LONG).show();
                    verifyStickersCount();
                    break;
                case CutOut.CUTOUT_ACTIVITY_RESULT_ERROR_CODE:
                    Exception ex = CutOut.getError(data);
                    Log.d("TESTTTTTT :::::",ex+"::DDD");
                    break;
                default:
                    System.out.print("User cancelled the CutOut screen");
            }
        } else if (requestCode == Define.ALBUM_REQUEST_CODE) {
            ArrayList<Uri> uries;
            if (resultCode == Activity.RESULT_OK) {
                uries = data.getParcelableArrayListExtra(Define.INTENT_PATH);
                CutOut.activity().src(uries.get(0)).intro().start(getActivity());
            }
        }
    }

    public class ImagesGridAdapter extends RecyclerView.Adapter<ImageViewHolder> {
        public ArrayList<Uri> uries = new ArrayList<>();
        Context context;

        public ImagesGridAdapter(Context context, ArrayList<Uri> uries) {
            this.uries = uries;
            this.context = context;
        }

        @NonNull
        @Override
        public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            final Context context = viewGroup.getContext();
            final LayoutInflater layoutInflater = LayoutInflater.from(context);
            final View view = layoutInflater.inflate(R.layout.sticker_created_item, viewGroup, false);
            return new ImageViewHolder(view);
        }

        @Override
        public void onBindViewHolder(@NonNull ImageViewHolder imageAdapter, int index) {
            imageAdapter.imageView.setImageURI(uries.get(index));
            imageAdapter.imageView.setPadding(8, 8, 8, 8);
            imageAdapter.imageView.setOnLongClickListener(v -> {
                PopupMenu popupMenu = new PopupMenu(context, imageAdapter.imageView);
                popupMenu.inflate(R.menu.sticker_menu);
                popupMenu.setOnMenuItemClickListener(item -> {
                    switch (item.getItemId()) {
                     /*  case R.id.add_to_exist_stickerpack:
                            addToStickerPack(index);
                            break;*/
                        case R.id.delete_sticker:
                            this.deleteSticker(index);
                            break;
                        default:
                            break;
                    }
                    return false;
                });
                popupMenu.show();
                return false;
            });
        }

        void deleteSticker(int index) {
            new AlertDialog.Builder(context)
                    .setTitle("Deleting")
                    .setMessage("Are you sure you want to delete this sticker?")
                    .setPositiveButton("Yes", (dialog, which) -> {
                        Uri uri = uries.get(index);
                        FileUtils.deleteFile(uri.getPath(),context);
                        uries.remove(index);
                        notifyItemRemoved(index);
                        notifyDataSetChanged();
                        Toast.makeText(context, "Deleted", Toast.LENGTH_SHORT).show();
                        verifyStickersCount();
                    })
                    .setNegativeButton("No", null)
                    .show();
        }

         void addToStickerPack(int index) {
            Intent intent = new Intent(context, AddToStickerPackActivity.class);
            intent.setData(uries.get(index));
            startActivity(intent);
        }

        @Override
        public int getItemCount() {
            return uries.size();
        }
    }

    class ImageViewHolder extends RecyclerView.ViewHolder {
        SimpleDraweeView imageView;

        public ImageViewHolder(@NonNull View itemView) {
            super(itemView);
            this.imageView = itemView.findViewById(R.id.sticker_created_image);
        }

    }
}

Body:
The problem is in directory path in Constants.STICKERS_CREATED_DIRECTORY_PATH. In Constant.java there some codes like below:

public final static String STICKERS_CREATED_DIRECTORY_PATH = Environment.getExternalStorageDirectory() + "/WA Stickers/My Created/";

then I specify the directory path

public final static String STICKERS_CREATED_DIRECTORY_PATH = Environment.getExternalStorageDirectory() + "/storage/emulated/0/WA Stickers/My Created/";

It works. Thanks for your answers.

Edited:
It works only in emulator. I tried installing in real device but the app force closed.

Edited:
problem solved. I installed the apk with different apk signer from previous apk that is already installed. so everything runs normally with codes above.


问:
Define a maximum number of line in a div
I create a  with a text inside but the text is too large for the div :

How can I stop the text when the div is stopping ?

答:
Just use to achieve that the overflow property in css:

div {
  border: solid black 3px;
  height: 60px;
  overflow: hidden;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</div></code>```

Please take a look at the documentation: https://www.w3schools.com/cssref/pr_pos_overflow.asp

Body:
Just use to achieve that the overflow property in css:

div {
  border: solid black 3px;
  height: 60px;
  overflow: hidden;
}

<div>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</div>

Please take a look at the documentation: https://www.w3schools.com/cssref/pr_pos_overflow.asp


问:
Redux-form-material-ui - use Select with onChange
I'm using redux-form-material-ui 5.0.0-beta.2 which is compatible with material ui v1.

I want to have a Select component where I can activate an onChange event when a choice is made, and I want the selected value to show in the Select field (as it should). If I use the redux-form-material-ui Select component I get the error:

```<code>Cannot read property 'onChange' of undefined
</code>```

I can reproduce it by taking the example on how to use redux-form with material ui here and replace the SelectField with redux-form-material-ui Select and put {children} between the open and close tag. You can see the same error:

Code example

^^ If you open this in Chrome you get the "Cannot read property 'onChange'.." error, but in Firefox it says "_ref$input is undefined".

Can this be fixed in some way:

```<code>import { Select } from 'redux-form-material-ui';

const renderSelectField = (
  { input, label, meta: { touched, error }, children, ...custom },
) => (
    <Select
      errorText={touched && error}
      {...input}
      onChange={(event, index, value) => input.onChange(value)}

      {...custom}
    >
      {children}
    </Select>
);
const MaterialUiForm = props => {
  const { handleSubmit, pristine, reset, submitting } = props;
  return (
    <form onSubmit={handleSubmit}>

      <div>
        <Field
          name="favoriteColor"
          component={renderSelectField}
          label="Favorite Color"
        >
          <MenuItem value="ff0000" primaryText="Red" />
          <MenuItem value="00ff00" primaryText="Green" />
          <MenuItem value="0000ff" primaryText="Blue" />
        </Field>
      </div>

//code continues..
</code>```

If I try a simpler approach using the example on redux-form-material-ui:
redux-form-material-ui/tree/5.0

```<code><Field
    name="plan"
    component={Select}
    onChange={(event, index, value) => input.onChange(value)}
    placeholder="Select a plan"
>
    <MenuItem value="monthly">Monthly</MenuItem>
    <MenuItem value="yearly">Yearly</MenuItem>
    <MenuItem value="lifetime">Lifetime</MenuItem>
  </Field>
</code>```

But it doesn't work if I add the onChange. When doing a selection it says:

```<code>props.input is undefined
</code>```

答:
You probably looked up the example in official Redux Form docs, but, just how it has been mentioned in the comment, they used SelectedField instead of Select component.

SelectField implements onChange method with 3 arguments, however Select uses just one. Use this instead.

```<code>onChange={value => input.onChange(value)}
</code>```

Body:
I'm using redux-form-material-ui 5.0.0-beta.2 which is compatible with material ui v1.

I want to have a Select component where I can activate an onChange event when a choice is made, and I want the selected value to show in the Select field (as it should). If I use the redux-form-material-ui Select component I get the error:

Cannot read property 'onChange' of undefined

I can reproduce it by taking the example on how to use redux-form with material ui here and replace the SelectField with redux-form-material-ui Select and put {children} between the open and close tag. You can see the same error:

Code example

^^ If you open this in Chrome you get the "Cannot read property 'onChange'.." error, but in Firefox it says "_ref$input is undefined".

Can this be fixed in some way:

import { Select } from 'redux-form-material-ui';

const renderSelectField = (
  { input, label, meta: { touched, error }, children, ...custom },
) => (
    <Select
      errorText={touched && error}
      {...input}
      onChange={(event, index, value) => input.onChange(value)}

      {...custom}
    >
      {children}
    </Select>
);
const MaterialUiForm = props => {
  const { handleSubmit, pristine, reset, submitting } = props;
  return (
    <form onSubmit={handleSubmit}>

        <Field
          name="favoriteColor"
          component={renderSelectField}
          label="Favorite Color"
        >
          <MenuItem value="ff0000" primaryText="Red" />
          <MenuItem value="00ff00" primaryText="Green" />
          <MenuItem value="0000ff" primaryText="Blue" />
        </Field>

//code continues..

If I try a simpler approach using the example on redux-form-material-ui:
redux-form-material-ui/tree/5.0

<Field
    name="plan"
    component={Select}
    onChange={(event, index, value) => input.onChange(value)}
    placeholder="Select a plan"
>
    <MenuItem value="monthly">Monthly</MenuItem>
    <MenuItem value="yearly">Yearly</MenuItem>
    <MenuItem value="lifetime">Lifetime</MenuItem>
  </Field>

But it doesn't work if I add the onChange. When doing a selection it says:

props.input is undefined

Body:
You probably looked up the example in official Redux Form docs, but, just how it has been mentioned in the comment, they used SelectedField instead of Select component.

SelectField implements onChange method with 3 arguments, however Select uses just one. Use this instead.

onChange={value => input.onChange(value)}


问:
Why I cannot set the value of this hash key?
```<code>task = {:project=>1000,
        :order=>0,
        :partial_image=>nil,
        :options=>{
           :height=>50,
           :width=>50,
           :start_row=>1,
           :start_column=>1,
           :end_row=>50,
           :end_column=>50,
           :scene=>0}}

project = redis.hget('active_projects', task[:project])
=>
{:name=>"Pov",
 :tasks=>
        {0=>
            {:project=>1000,
             :order=>0,
             :partial_image=>nil,
             :options=>
                 {:height=>50,
                  :width=>50,
                  :start_row=>1,
                  :start_column=>1,
                  :end_row=>50,
                  :end_column=>50,
                  :scene=>"blabla"
                 }
             }
         },
  :id=>1000,
  :image=>"",
  :options=>
        {:height=>100,
         :width=>50,
         :scene=>"blabla"
        }
   }

task[:partial_image] = 'blablabla'
project[:tasks][task[:order]] = task    # this is line 37

 Failure/Error: completed_task = DPovray::Task.perform(task)
 TypeError:
   can't convert Symbol into Integer
 # ./lib/jobs/job.rb:37:in `[]'
 # ./lib/jobs/job.rb:37:in `block in perform'
 # ./lib/jobs/job.rb:35:in `perform'
 # ./spec/task_spec.rb:22:in `block (4 levels) in <top (required)>'
</code>```

The code is in https://github.com/Nerian/DPovray

The test that fails can be run with  rspec spec/task_spec.rb

答:
Actually project = redis.hget('active_projects', task[:project]) is returning a string, not a ruby hash. So that is why it fails.

I am playing with https://github.com/nateware/redis-objects to see if I can do what I want to do.

Also, instead of doing:

```<code>Redis.new.hset('active_projects', active_project[:id], active_project)
</code>```

You can do:

```<code>Redis.new.hset('active_projects', active_project[:id], Marshal.dump(active_project))
</code>```

And it just works, thanks to hash marshaling.

Nonetheless, I do not consider this a good solution. I don't like to use Marshaling as it is much difficult do debug by looking at the database.

Also I just got a:

```<code> incompatible marshal file format (can't be read)
    format version 4.8 required; 123.58 given
</code>```

So let us discover a different approach...

edit:

Now I am playing with JSON.dump and JSON.parse.  They seem a better approach.

Edit:

I ended up encapsulating this hash into a real object. So I have Project class and a Task class. In each one I define the methods to_json and self.json_create(o) to that they can be convert to and from JSON.

It works quite well.

Body:
task = {:project=>1000,
        :order=>0,
        :partial_image=>nil,
        :options=>{
           :height=>50,
           :width=>50,
           :start_row=>1,
           :start_column=>1,
           :end_row=>50,
           :end_column=>50,
           :scene=>0}}

project = redis.hget('active_projects', task[:project])
=>
{:name=>"Pov",
 :tasks=>
        {0=>
            {:project=>1000,
             :order=>0,
             :partial_image=>nil,
             :options=>
                 {:height=>50,
                  :width=>50,
                  :start_row=>1,
                  :start_column=>1,
                  :end_row=>50,
                  :end_column=>50,
                  :scene=>"blabla"
                 }
             }
         },
  :id=>1000,
  :image=>"",
  :options=>
        {:height=>100,
         :width=>50,
         :scene=>"blabla"
        }
   }

task[:partial_image] = 'blablabla'
project[:tasks][task[:order]] = task    # this is line 37

 Failure/Error: completed_task = DPovray::Task.perform(task)
 TypeError:
   can't convert Symbol into Integer
 # ./lib/jobs/job.rb:37:in `[]'
 # ./lib/jobs/job.rb:37:in `block in perform'
 # ./lib/jobs/job.rb:35:in `perform'
 # ./spec/task_spec.rb:22:in `block (4 levels) in <top (required)>'

The code is in https://github.com/Nerian/DPovray

The test that fails can be run with  rspec spec/task_spec.rb

Body:
Actually project = redis.hget('active_projects', task[:project]) is returning a string, not a ruby hash. So that is why it fails.

I am playing with https://github.com/nateware/redis-objects to see if I can do what I want to do.

Also, instead of doing:

Redis.new.hset('active_projects', active_project[:id], active_project)

You can do:

Redis.new.hset('active_projects', active_project[:id], Marshal.dump(active_project))

And it just works, thanks to hash marshaling.

Nonetheless, I do not consider this a good solution. I don't like to use Marshaling as it is much difficult do debug by looking at the database.

Also I just got a:

 incompatible marshal file format (can't be read)
    format version 4.8 required; 123.58 given

So let us discover a different approach...

edit:

Now I am playing with JSON.dump and JSON.parse.  They seem a better approach.

Edit:

I ended up encapsulating this hash into a real object. So I have Project class and a Task class. In each one I define the methods to_json and self.json_create(o) to that they can be convert to and from JSON.

It works quite well.


问:
How to correctly take a Date object passed with state in React into datepicker?
I'm using DatePicker with my react app. I pass an object which contains a date field from one component to another via location.state. This is an editing component, where I can change the values of these fields. But the console swears with invalid time exception. I read I should do something with parseISO but still it does nothing. How to properly use it? (settings is a this.state field)</p>

```<code>...
import DatePicker from 'react-datepicker'
import 'react-datepicker/dist/react-datepicker.css'
import { parseISO, format } from 'date-fns'
...

            <DatePicker
              name="saleDateFrom"
              selected={parseISO(settings.saleDateFrom)}
              onChange={this.handleChangeFrom}
              dateFormat="MMMM dd, yyyy hh:mm:ss aa"
            />
</code>```

答:
```<code>   <DatePicker
          name="saleDateFrom"
          selected={new Date(settings.saleDateFrom)}
          onChange={this.handleChangeFrom}
          dateFormat="MMMM dd, yyyy hh:mm:ss aa"
        />
</code>```

This will take care of your issues. react-datepicker expects date as javascript Date objects

Body:
I'm using DatePicker with my react app. I pass an object which contains a date field from one component to another via location.state. This is an editing component, where I can change the values of these fields. But the console swears with invalid time exception. I read I should do something with parseISO but still it does nothing. How to properly use it? (settings is a this.state field)

...
import DatePicker from 'react-datepicker'
import 'react-datepicker/dist/react-datepicker.css'
import { parseISO, format } from 'date-fns'
...

            <DatePicker
              name="saleDateFrom"
              selected={parseISO(settings.saleDateFrom)}
              onChange={this.handleChangeFrom}
              dateFormat="MMMM dd, yyyy hh:mm:ss aa"
            />

Body:
   <DatePicker
          name="saleDateFrom"
          selected={new Date(settings.saleDateFrom)}
          onChange={this.handleChangeFrom}
          dateFormat="MMMM dd, yyyy hh:mm:ss aa"
        />

This will take care of your issues. react-datepicker expects date as javascript Date objects


答:
Try This</p>

```<code><div class='text'>
*your text here*
</div>

<style>
.text{
overflow-y: scroll;
height:400px;
}
</style>
</code>```

Title: Define a maximum number of line in a div

Body:
I create a  with a text inside but the text is too large for the div :

How can I stop the text when the div is stopping ?

Body:
Try This

<div class='text'>
*your text here*
</div>

<style>
.text{
overflow-y: scroll;
height:400px;
}
</style>


问:
using git send-mail with google 2-factor authentication
I'd like to use git send-mail to submit patches upstream, but my gmail account is using two factor authentication. Google provides app specific passwords for things like this, but my question is where is a secure place to store this password for use with git send-mail?

答:
For those who don't want to use their Gmail password for this, I wrote a plug-in for git-send-email that uses OAuth 2 authorization. It requests only the minimum required permissions (send email on your behalf) and stores OAuth token data in Windows Credential Store, like Git Credential Manager does.

UPDATE: Google has a plug-in which works in a similar fashion, but keeps credentials in a file, and uses less restricted tokens (all of Gmail vs just send email on your behalf). It works on Linux though.


问:
binding to width property in code behind
I have a situation where I need to create View box with one button. The xaml for this is as below: Please observe Width property of viewbox. The Width should be increased/decreased according to a slider bar(moving to right increases it, to left decreases it). As listed below I know how to do it in xaml and it works fine. But my requirement is to be able to create viewbox in code behind and assign it the properties.

```<code> <WrapPanel x:Name="_wrpImageButtons" Grid.IsSharedSizeScope="True"
           ScrollViewer.CanContentScroll="True" d:LayoutOverrides="Height"
           Margin="5">
    <Viewbox x:Name="_ScaleButton"
             Width="{Binding Value, ElementName=ZoomSlider}" Stretch="Fill">
         <CustomButton:_uscVCARSImagesButton x:Name="_btnImage1"/>
    </Viewbox>
 </WrapPanel>
</code>```

Thanks.

答:
You can create the binding relatively easily in Code Behind:</p>

```<code>var widthBinding = new Binding("Value") { ElementName = "ZoomSlider" };

_ScaleButton.SetBinding(FrameworkElement.WidthProperty, widthBinding);
</code>```

Body:
I have a situation where I need to create View box with one button. The xaml for this is as below: Please observe Width property of viewbox. The Width should be increased/decreased according to a slider bar(moving to right increases it, to left decreases it). As listed below I know how to do it in xaml and it works fine. But my requirement is to be able to create viewbox in code behind and assign it the properties.

 <WrapPanel x:Name="_wrpImageButtons" Grid.IsSharedSizeScope="True"
           ScrollViewer.CanContentScroll="True" d:LayoutOverrides="Height"
           Margin="5">
    <Viewbox x:Name="_ScaleButton"
             Width="{Binding Value, ElementName=ZoomSlider}" Stretch="Fill">
         <CustomButton:_uscVCARSImagesButton x:Name="_btnImage1"/>
    </Viewbox>
 </WrapPanel>

Thanks.

Body:
You can create the binding relatively easily in Code Behind:

var widthBinding = new Binding("Value") { ElementName = "ZoomSlider" };

_ScaleButton.SetBinding(FrameworkElement.WidthProperty, widthBinding);