问:
Using Sikuli Finder() to search screenshot with icon, providing cached like response when used in a loop
(Using Sikuli IDE -288 20/04/19 on Windows 10)

I am currently having issues with a portion of code that runs correctly the first time around, but the second time where the function is looped instead of overwriting information created in the first iteration, it is somehow using the old information.

A function called selectRewards() is called, and it takes a few screenshots of the reward region over a few seconds to gather a useable still of an animation, the file name is numerically incremented. Then the function creates a Finder using the screenshots starting with screenshot 1. The Finder, and image I want to check against is passed into a search() function where it should be using the passed finder and image to find matches. It checks for all defined images in screenshot1, screenshot2 etc. until matches are found. And the matches are selected on the screen using coordinates from the screenshot image.

This all works well in the first iteration of the selectRewards(), it cycles through the screenshots and finds the images on a stable screenshot, but when the function is called again the same exact "found" results are returned, and clicks are exactly the same even when the images don't exist in the screenshots (I've even deleted the screenshots at the end of the first loop to try and clear any incorrect information being sent to the finder.

I've tried to pull the section out to share in a cleaner way, and it still provides the same issue. Any help and advice would be deeply appreciated.

(Though currently having even stranger issues with the code, since having the main script open in a tab on the IDE and the new script in another - neither running - if I run the snippet script it will use the coordinates/image finds from a previous run of the scripts). Can there be some sort of memory issue or caching in windows? ALT+SHIFT+R to restart the IDE normally helps clear the issue.

Settings.MoveMouseDelay = 0.5
#Define Regions
rewardRegion = Region(536,429,832,207)
#Define Images
searchCoupons = Pattern("coupons.png").similar(0.85)
searchAdvanced = Pattern("2011.png").similar(0.85)
searchAdvancedFrag = Pattern("2012.png").similar(0.85)

matchesFound = False

def search(image,rewardGlimpse, descr = ""):
    print ("##### searching for: (%s) %s" % (image, descr))
    rewardGlimpse.findAll(image) # find all matches (using passed finder variable & image variable)
    matches = [] # an empty list to store the matches
    while rewardGlimpse.hasNext(): # loop as long there is a first and more matches
        matches.append(rewardGlimpse.next())        # access next match and add to matches
        # now we have our matches saved in the list matches
    print("   Does FindAll have next? (should be false):" + str(rewardGlimpse.hasNext()))
    print("   Found matches:" + str(len(matches)))

    if len(matches) > 0:
        global matchesFound
        matchesFound = True
        obtainedReward = str(descr)
        print("   Match found should be true " + str(matchesFound) + ". Found: "+obtainedReward)

        # we want to use our matches
    for m in matches:
        #Find x & y location of rewards in screenshot
        matchx = m.x
        matchy = m.y
        #Append them to the reward region to line it up.
        newx = rewardRegion.getX()+matchx
        newy = rewardRegion.getY()+matchy
        rewardHover = Location(newx, newy)
        #click the found reward location
        click(rewardHover)
        wait(1)

def selectRewards():
    #---- Save Incremental Screenshots
    wait(1)
    capture(rewardRegion,"screenshot1.png")
    wait(0.5)
    capture(rewardRegion,"screenshot2.png")
    wait(0.5)
    capture(rewardRegion,"screenshot3.png")
    wait(0.5)
    capture(rewardRegion,"screenshot4.png")
    wait(0.5)
    capture(rewardRegion,"screenshot5.png")
    wait(0.5)
    capture(rewardRegion,"screenshot6.png")
    wait(0.5)
    #----- Test the screenshots
    snum = 1 #screenshot file number

    while True:
        global matchesFound
        if matchesFound == True:
            print("Rewards Found - breaking search loop")
            matchesFound = False
            break
        else:
            pass

        #Start with _screenshot1.png, increment snum.
        screenshotURL = "_screenshot"+str(snum)+".png"
        rewardGlimpse = Finder(screenshotURL) #Setup the Finder

        print("Currently searching in: " + str(screenshotURL))

        #Pass along the image to search, the screenshots Finder, and description.
        search(searchCoupons,rewardGlimpse, "Coupons")
        search(searchAdvanced,rewardGlimpse, "Advanced Recruit Proof")
        search(searchAdvancedFrag,rewardGlimpse, "Advanced Recruit Fragments")
        snum = snum + 1
        if snum>6:
            break

    while True: #All rewards available this round are collected
        if exists("1558962266403.png"):
            click("1558962266403.png")
            #confirm
            break
        else:
            pass
        print("No reward found at this point.")
        print("Matches Found at No Reward Debug: " +str(matchesFound))
        #Needed matches not found, selecting random reward.
        hover("1558979979033.png")
        click("1558980645042.png")
        #matchesFound = False #Toggle back to False

        #print("Matches found: Variable Value(Should be false)" + str(matchesFound))

def main():
    i = 0
    SSLoops = 2
    while i < 2:
        print("Loop #" + str(i+1) + "/"+ str(SSLoops))
        print("--------------")
        if i == 1: #remove this if statement for live
            click("1559251066942.png") #switches spoofed html pages to show diff rewards

        selectRewards()
        i = i + 1

if __name__ == '__main__':
    main()
```

<p>Loop one of calling <code>selectRewards()</code> is correct, there were 3 images in the reward region that matched the things to search for. But the second loop is incorrect, only one of the matching images were there and wasn't in the same exact position. The script clicked in the 3 locations of the previous loop during the second time around.</p>

<p>Message log:
    ====</p>

```Loop #1/2
--------------

Currently searching in: _screenshot1.png
##### searching for: (P(coupons.png) S: 0.85) Coupons

Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Coupons

[log] CLICK on L[603,556]@S(0) (586 msec)

##### searching for: (P(2011.png) S: 0.85) Advanced Recruit Proof

Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Advanced Recruit Proof

[log] CLICK on L[653,556]@S(0) (867 msec)

##### searching for: (P(2012.png) S: 0.85) Advanced Recruit Fragments

Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Advanced Recruit Fragments

[log] CLICK on L[703,556]@S(0) (539 msec)

Rewards Found - breaking search loop

[log] CLICK on L[90,163]@S(0) (541 msec)

Loop #2/2

--------------

[log] CLICK on L[311,17]@S(0) (593 msec)

Currently searching in: _screenshot1.png
##### searching for: (P(coupons.png) S: 0.85) Coupons

Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Coupons

[log] CLICK on L[603,556]@S(0) (617 msec)

##### searching for: (P(2011.png) S: 0.85) Advanced Recruit Proof
Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Advanced Recruit Proof

[log] CLICK on L[653,556]@S(0) (535 msec)

##### searching for: (P(2012.png) S: 0.85) Advanced Recruit Fragments
Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Advanced Recruit Fragments

[log] CLICK on L[703,556]@S(0) (539 msec)

Rewards Found - breaking search loop

[log] CLICK on L[304,289]@S(0) (687 msec)

====
```

答:
RaiMan from SikuliX:

ok, the reason is the image caching internally based on filenames.
When a new Finder is created with an image filename already in cache, the cached version is used.

So you either might switch off caching globally:
Settings.setImageCache(0)

or add:
Image.reset()

at the beginning of selectRewards()

or add the loop count to the filename of the captured images (take care: memory is constantly increased!)

BTW: when selecting another tab in the IDE, the images from the previously selected tab are uncached automatically.

Body:
(Using Sikuli IDE -288 20/04/19 on Windows 10)

I am currently having issues with a portion of code that runs correctly the first time around, but the second time where the function is looped instead of overwriting information created in the first iteration, it is somehow using the old information.

A function called selectRewards() is called, and it takes a few screenshots of the reward region over a few seconds to gather a useable still of an animation, the file name is numerically incremented. Then the function creates a Finder using the screenshots starting with screenshot 1. The Finder, and image I want to check against is passed into a search() function where it should be using the passed finder and image to find matches. It checks for all defined images in screenshot1, screenshot2 etc. until matches are found. And the matches are selected on the screen using coordinates from the screenshot image.

This all works well in the first iteration of the selectRewards(), it cycles through the screenshots and finds the images on a stable screenshot, but when the function is called again the same exact "found" results are returned, and clicks are exactly the same even when the images don't exist in the screenshots (I've even deleted the screenshots at the end of the first loop to try and clear any incorrect information being sent to the finder.

I've tried to pull the section out to share in a cleaner way, and it still provides the same issue. Any help and advice would be deeply appreciated.

(Though currently having even stranger issues with the code, since having the main script open in a tab on the IDE and the new script in another - neither running - if I run the snippet script it will use the coordinates/image finds from a previous run of the scripts). Can there be some sort of memory issue or caching in windows? ALT+SHIFT+R to restart the IDE normally helps clear the issue.

Settings.MoveMouseDelay = 0.5
#Define Regions
rewardRegion = Region(536,429,832,207)
#Define Images
searchCoupons = Pattern("coupons.png").similar(0.85)
searchAdvanced = Pattern("2011.png").similar(0.85)
searchAdvancedFrag = Pattern("2012.png").similar(0.85)

matchesFound = False

def search(image,rewardGlimpse, descr = ""):
    print ("##### searching for: (%s) %s" % (image, descr))
    rewardGlimpse.findAll(image) # find all matches (using passed finder variable & image variable)
    matches = [] # an empty list to store the matches
    while rewardGlimpse.hasNext(): # loop as long there is a first and more matches
        matches.append(rewardGlimpse.next())        # access next match and add to matches
        # now we have our matches saved in the list matches
    print("   Does FindAll have next? (should be false):" + str(rewardGlimpse.hasNext()))
    print("   Found matches:" + str(len(matches)))

    if len(matches) > 0:
        global matchesFound
        matchesFound = True
        obtainedReward = str(descr)
        print("   Match found should be true " + str(matchesFound) + ". Found: "+obtainedReward)

        # we want to use our matches
    for m in matches:
        #Find x & y location of rewards in screenshot
        matchx = m.x
        matchy = m.y
        #Append them to the reward region to line it up.
        newx = rewardRegion.getX()+matchx
        newy = rewardRegion.getY()+matchy
        rewardHover = Location(newx, newy)
        #click the found reward location
        click(rewardHover)
        wait(1)

def selectRewards():
    #---- Save Incremental Screenshots
    wait(1)
    capture(rewardRegion,"screenshot1.png")
    wait(0.5)
    capture(rewardRegion,"screenshot2.png")
    wait(0.5)
    capture(rewardRegion,"screenshot3.png")
    wait(0.5)
    capture(rewardRegion,"screenshot4.png")
    wait(0.5)
    capture(rewardRegion,"screenshot5.png")
    wait(0.5)
    capture(rewardRegion,"screenshot6.png")
    wait(0.5)
    #----- Test the screenshots
    snum = 1 #screenshot file number

    while True:
        global matchesFound
        if matchesFound == True:
            print("Rewards Found - breaking search loop")
            matchesFound = False
            break
        else:
            pass

        #Start with _screenshot1.png, increment snum.
        screenshotURL = "_screenshot"+str(snum)+".png"
        rewardGlimpse = Finder(screenshotURL) #Setup the Finder

        print("Currently searching in: " + str(screenshotURL))

        #Pass along the image to search, the screenshots Finder, and description.
        search(searchCoupons,rewardGlimpse, "Coupons")
        search(searchAdvanced,rewardGlimpse, "Advanced Recruit Proof")
        search(searchAdvancedFrag,rewardGlimpse, "Advanced Recruit Fragments")
        snum = snum + 1
        if snum>6:
            break

    while True: #All rewards available this round are collected
        if exists("1558962266403.png"):
            click("1558962266403.png")
            #confirm
            break
        else:
            pass
        print("No reward found at this point.")
        print("Matches Found at No Reward Debug: " +str(matchesFound))
        #Needed matches not found, selecting random reward.
        hover("1558979979033.png")
        click("1558980645042.png")
        #matchesFound = False #Toggle back to False

        #print("Matches found: Variable Value(Should be false)" + str(matchesFound))

def main():
    i = 0
    SSLoops = 2
    while i < 2:
        print("Loop #" + str(i+1) + "/"+ str(SSLoops))
        print("--------------")
        if i == 1: #remove this if statement for live
            click("1559251066942.png") #switches spoofed html pages to show diff rewards

        selectRewards()
        i = i + 1

if __name__ == '__main__':
    main()

Loop one of calling selectRewards() is correct, there were 3 images in the reward region that matched the things to search for. But the second loop is incorrect, only one of the matching images were there and wasn't in the same exact position. The script clicked in the 3 locations of the previous loop during the second time around.

Message log:
    ====

Loop #1/2
--------------

Currently searching in: _screenshot1.png
##### searching for: (P(coupons.png) S: 0.85) Coupons

Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Coupons

[log] CLICK on L[603,556]@S(0) (586 msec)

##### searching for: (P(2011.png) S: 0.85) Advanced Recruit Proof

Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Advanced Recruit Proof

[log] CLICK on L[653,556]@S(0) (867 msec)

##### searching for: (P(2012.png) S: 0.85) Advanced Recruit Fragments

Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Advanced Recruit Fragments

[log] CLICK on L[703,556]@S(0) (539 msec)

Rewards Found - breaking search loop

[log] CLICK on L[90,163]@S(0) (541 msec)

Loop #2/2

--------------

[log] CLICK on L[311,17]@S(0) (593 msec)

Currently searching in: _screenshot1.png
##### searching for: (P(coupons.png) S: 0.85) Coupons

Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Coupons

[log] CLICK on L[603,556]@S(0) (617 msec)

##### searching for: (P(2011.png) S: 0.85) Advanced Recruit Proof
Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Advanced Recruit Proof

[log] CLICK on L[653,556]@S(0) (535 msec)

##### searching for: (P(2012.png) S: 0.85) Advanced Recruit Fragments
Does FindAll have next? (should be false):False
Found matches:1
Match found should be true True. Found: Advanced Recruit Fragments

[log] CLICK on L[703,556]@S(0) (539 msec)

Rewards Found - breaking search loop

[log] CLICK on L[304,289]@S(0) (687 msec)

====


来源: stackexchange

问:
Angular 4 Webpack 2 & AOT: Unexpected closing tag "a"
I am getting this weird error when I am making a build, at the time of watch or running server its not giving anything, just only at the time of build giving this error:

Unexpected closing tag "a". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags ("ref=/user>[ERROR ->] <search class="mr-auto col-sm-7 col-md-6 col-lg-5 col-xl-5 p-0"></search>
 <div"): ng:///Users/header.html@0:192

And here is my html:

```<code><nav class="navbar d-flex flex-row navbar-light bg-faded fixed-top">
    <a class="navbar-brand" href="/user"><img class="d-inline-block align-top" [src]="staticUrl + 'v4/img/intouch-logo-name.png'" /></a>

    <search class="mr-auto col-sm-7 col-md-6 col-lg-5 col-xl-5 p-0"></search>

    <div id="settings">
        <div class="dropdown clearfix">
            <div class="userProfile dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <div class="userDetail">
                    <label>
                        {{loggedUser.icontact.name.given + ((loggedUser.icontact.name.family) ? ' '+loggedUser.icontact.name.family : '')}}
                    </label>
                    <small>
                        {{loggedUser.icontact.user_iid}}
                    </small>
                </div>
                <img class="profilePic rounded-circle" [src]="(loggedUser.icontact.photo) ? loggedUser.icontact.photo.url : staticUrl + 'images/in_img_default_profile_100px.png'" />
            </div>
            <div class="dropdown-menu" aria-labelledby="settings">
                <a class="dropdown-item" [href]="'/' + loggedUser.icontact.user_iid" target="_blank">View profile</a>
                <a class="dropdown-item" href="/user/cards/" target="_blank">
                    Edit Profile
                </a>
                <div class="dropdown-divider"
                    *ngIf="accountInfo.userStatus.currentUserType == accountInfo.userStatus.groupType"></div>
                <a class="dropdown-item" href="/user/notices/" target="_blank"
                    *ngIf="accountInfo.userStatus.currentUserType == accountInfo.userStatus.groupType">Notices</a>
                <div class="dropdown-divider"></div>
                <a class="dropdown-item upgrade-link upgrade-account" href="/user/upgrade/" target="_blank"
                    *ngIf="accountInfo.userStatus.currentPlan == '001'">Upgrade</a>
                <a class="dropdown-item" href="mailto:support@intouchid.net?Subject=Feedback%20on%20the%20new%20interface">Feedback</a>
                <a class="dropdown-item" href="/user/import/" target="_blank">Import data</a>
                <div class="dropdown-divider"></div>
                <a class="dropdown-item" href="/user/">Switch to old view</a>
                <div class="dropdown-divider"></div>
                <a class="dropdown-item" href="/logout/"
                    (click)="utilsService.sendEvent('spreadsheet_view', 'logout_clicked', 'clicked on logout')">Logout</a>
            </div>
        </div>
    </div>
</nav>
</code>```

And this is the script I am using to make a build: npm run cleanup && npm run ngc && webpack --config config/webpack.prod.js -p & my webpack config is:

```<code>plugins: [
    new AotPlugin({
      tsConfigPath: './tsconfig.json',
      entryModule: helpers.root('src/app/app.module#AppModule')
    }),
    new webpack.LoaderOptionsPlugin({
      debug: true,  // config.debug has to be passed this way now too!
      htmlLoader: {
        minimize: false
      }
    }),
    new webpack.NoErrorsPlugin(),
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
      mangle: {
        keep_fnames: true
      }
    }),
    new ExtractTextPlugin('[name].[hash].css'),
    new webpack.DefinePlugin({
      'process.env': {
        'ENV': JSON.stringify(ENV)
      }
    }),
    new CompressionPlugin()
  ]
</code>```

答:
In my case the error was due to the minimization of HTML. Turning it off resolved the issue. To turn it off correctly please review the docs here: https://webpack.js.org/loaders/html-loader

module: {
  rules: [{
    test: /\.html$/,
    use: [ {
      loader: 'html-loader',
      options: {
        minimize: false
      }
    }],
  }]
}
```

ContentLicense: CC BY-SA 3.0

Body:
I am getting this weird error when I am making a build, at the time of watch or running server its not giving anything, just only at the time of build giving this error:

Unexpected closing tag "a". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags ("ref=/user>[ERROR ->] <search class="mr-auto col-sm-7 col-md-6 col-lg-5 col-xl-5 p-0"></search>
 <div"): ng:///Users/header.html@0:192

And here is my html:

    <search class="mr-auto col-sm-7 col-md-6 col-lg-5 col-xl-5 p-0"></search>

                        {{loggedUser.icontact.name.given + ((loggedUser.icontact.name.family) ? ' '+loggedUser.icontact.name.family : '')}}

                        {{loggedUser.icontact.user_iid}}

                View profile

                    Edit Profile

                Notices

                Upgrade
                Feedback
                Import data

                Switch to old view

                Logout

And this is the script I am using to make a build: npm run cleanup && npm run ngc && webpack --config config/webpack.prod.js -p & my webpack config is:

plugins: [
    new AotPlugin({
      tsConfigPath: './tsconfig.json',
      entryModule: helpers.root('src/app/app.module#AppModule')
    }),
    new webpack.LoaderOptionsPlugin({
      debug: true,  // config.debug has to be passed this way now too!
      htmlLoader: {
        minimize: false
      }
    }),
    new webpack.NoErrorsPlugin(),
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
      mangle: {
        keep_fnames: true
      }
    }),
    new ExtractTextPlugin('[name].[hash].css'),
    new webpack.DefinePlugin({
      'process.env': {
        'ENV': JSON.stringify(ENV)
      }
    }),
    new CompressionPlugin()
  ]

ContentLicense: CC BY-SA 4.0


问:
Enabling and then disabling reactive events based on user input
I am trying to create an app that allows the user to search on a custom term, The logic i am trying to create is the user, inputs a string, and presses ENTER on the key board, the the search term is executed, this has been achievable. However in the example below after you press the enter button, it executes all changes, in the textinput

I have tried resetting the last key to empty, etc but have had no luck figuring out this little problem, simplified code below

```<code>library(shiny)

ui <- fluidPage(

   # Application title
   titlePanel("example"),

   fluidRow(
     column( 3, offset = 1,
             tags$script(' $(document).on("keydown", function (e) {
                                                  Shiny.onInputChange("lastkeypresscode", e.keyCode);
                                                  });
                                                  '),
     textInput("searchtext",
               label = "Text input",
               value = "")),
     column( 4, textOutput("mysearch")),
     column( 4)
    )

server <- function(input, output) {
  observe({
    if(!is.null(input$lastkeypresscode)){
      if(input$lastkeypresscode == 13){
         output$mysearch <- renderText(input$searchtext)

      }
    }
  })
}

# Run the application
shinyApp(ui = ui, server = server)
</code>```

The expected output is that changes should only be seen in the text out put after the ENTER key is pressed

答:
You can attach an onKeyPress event handler to the text input:

```<code>library(shiny)

textInput2 <- function(inputId, label, value = "", width = NULL, placeholder = NULL){
  input <- textInput(inputId, label, value, width, placeholder)
  input$children[[2]] <-
    htmltools::tagAppendAttributes(
      input$children[[2]],
      onKeyPress = sprintf("Shiny.setInputValue('%s_keypress', event.key)", inputId))
  input
}

ui <- fluidPage(
  textInput2("textinput", "Enter text:"),
  textOutput("textoutput")
)

server <- function(input, output){
  observeEvent(input[["textinput_keypress"]], {
    if(input[["textinput_keypress"]] == "Enter"){
      output[["textoutput"]] <- renderText({
        input[["textinput"]]
      })
    }
  })
}

shinyApp(ui, server)
</code>```

Some people say that it is not recommended to define an output inside an observer. To avoid that, you can do:

```<code>server <- function(input, output){

  Text <- eventReactive(input[["textinput_keypress"]], {
    req(input[["textinput_keypress"]] == "Enter")
    input[["textinput"]]
  })

  output[["textoutput"]] <- renderText({
    Text()
  })

}
</code>```

Alternatively, see this answer. But the present answer is better, I think.

EDIT

The OP claims that does not work. Maybe a more robust solution is:

```<code>onKeyPress = sprintf("Shiny.setInputValue('%s_keypress', event.which)", inputId)
</code>```

and replace

```<code>input[["textinput_keypress"]] == "Enter"
</code>```

with

```<code>input[["textinput_keypress"]] == 13
</code>```

Body:
I am trying to create an app that allows the user to search on a custom term, The logic i am trying to create is the user, inputs a string, and presses ENTER on the key board, the the search term is executed, this has been achievable. However in the example below after you press the enter button, it executes all changes, in the textinput

I have tried resetting the last key to empty, etc but have had no luck figuring out this little problem, simplified code below

library(shiny)

ui <- fluidPage(

   # Application title
   titlePanel("example"),

   fluidRow(
     column( 3, offset = 1,
             tags$script(' $(document).on("keydown", function (e) {
                                                  Shiny.onInputChange("lastkeypresscode", e.keyCode);
                                                  });
                                                  '),
     textInput("searchtext",
               label = "Text input",
               value = "")),
     column( 4, textOutput("mysearch")),
     column( 4)
    )

server <- function(input, output) {
  observe({
    if(!is.null(input$lastkeypresscode)){
      if(input$lastkeypresscode == 13){
         output$mysearch <- renderText(input$searchtext)

      }
    }
  })
}

# Run the application
shinyApp(ui = ui, server = server)

The expected output is that changes should only be seen in the text out put after the ENTER key is pressed

Body:
You can attach an onKeyPress event handler to the text input:

library(shiny)

textInput2 <- function(inputId, label, value = "", width = NULL, placeholder = NULL){
  input <- textInput(inputId, label, value, width, placeholder)
  input$children[[2]] <-
    htmltools::tagAppendAttributes(
      input$children[[2]],
      onKeyPress = sprintf("Shiny.setInputValue('%s_keypress', event.key)", inputId))
  input
}

ui <- fluidPage(
  textInput2("textinput", "Enter text:"),
  textOutput("textoutput")
)

server <- function(input, output){
  observeEvent(input[["textinput_keypress"]], {
    if(input[["textinput_keypress"]] == "Enter"){
      output[["textoutput"]] <- renderText({
        input[["textinput"]]
      })
    }
  })
}

shinyApp(ui, server)

Some people say that it is not recommended to define an output inside an observer. To avoid that, you can do:

server <- function(input, output){

  Text <- eventReactive(input[["textinput_keypress"]], {
    req(input[["textinput_keypress"]] == "Enter")
    input[["textinput"]]
  })

  output[["textoutput"]] <- renderText({
    Text()
  })

}

Alternatively, see this answer. But the present answer is better, I think.

EDIT

The OP claims that does not work. Maybe a more robust solution is:

onKeyPress = sprintf("Shiny.setInputValue('%s_keypress', event.which)", inputId)

and replace

input[["textinput_keypress"]] == "Enter"

with

input[["textinput_keypress"]] == 13


问:
Divide customers in classes based on the number of purchases and find who belongs in what range?
I have a table called: purchases

```<code>id |id_customer|id_product|date_of_purchase
1    1             1         2019-03-04
2    2             2         2019-02-05
3    3             3         2019-01-03
4    4             4         2019-01-10
5    5             5         2019-01-02
6    1             1         2019-03-05
7    1             3         2019-03-23
8    1             4         2019-03-23
9    1             3         2019-03-12
10   2             3         2019-03-23
11   2             1         2019-03-11
</code>```

Here is the code I have tried:

```<code>SELECT id_customer , count(id_customer) as times_bought,
CASE
    WHEN times_bought < 2 THEN "rare"
    WHEN times_bought >1 and times_bought < 4 THEN "neutral"
    ELSE "frequent"
END
FROM purchases;
</code>```

aside from the fact that the script may have many issues it gives times_bought is not a known column. What do you suggest?

答:
You are missing group by and checking count() instead of times_bought (which is not allowed) in the CASE statement:

```<code>SELECT id_customer, count(date_of_purchase) as times_bought,
  CASE count(date_of_purchase)
    WHEN 1 THEN 'rare'
    WHEN 2 THEN 'neutral'
    WHEN 3 THEN 'neutral'
    ELSE 'frequent'
  END customerclass
FROM purchases
GROUP BY id_customer
</code>```

See the demo.

Results:

```<code>| id_customer | times_bought | customerclass |
| ----------- | ------------ | ------------- |
| 1           | 5            | frequent      |
| 2           | 3            | neutral       |
| 3           | 1            | rare          |
| 4           | 1            | rare          |
| 5           | 1            | rare          |
</code>```

Body:
I have a table called: purchases

id |id_customer|id_product|date_of_purchase
1    1             1         2019-03-04
2    2             2         2019-02-05
3    3             3         2019-01-03
4    4             4         2019-01-10
5    5             5         2019-01-02
6    1             1         2019-03-05
7    1             3         2019-03-23
8    1             4         2019-03-23
9    1             3         2019-03-12
10   2             3         2019-03-23
11   2             1         2019-03-11

Here is the code I have tried:

SELECT id_customer , count(id_customer) as times_bought,
CASE
    WHEN times_bought < 2 THEN "rare"
    WHEN times_bought >1 and times_bought < 4 THEN "neutral"
    ELSE "frequent"
END
FROM purchases;

aside from the fact that the script may have many issues it gives times_bought is not a known column. What do you suggest?

Body:
You are missing group by and checking count() instead of times_bought (which is not allowed) in the CASE statement:

SELECT id_customer, count(date_of_purchase) as times_bought,
  CASE count(date_of_purchase)
    WHEN 1 THEN 'rare'
    WHEN 2 THEN 'neutral'
    WHEN 3 THEN 'neutral'
    ELSE 'frequent'
  END customerclass
FROM purchases
GROUP BY id_customer

See the demo.

Results:

| id_customer | times_bought | customerclass |
| ----------- | ------------ | ------------- |
| 1           | 5            | frequent      |
| 2           | 3            | neutral       |
| 3           | 1            | rare          |
| 4           | 1            | rare          |
| 5           | 1            | rare          |


问:
No redirection after successful angular form validation
Today, I encountered a problem with angular routing after successful validation of Angular reactive form. All I want to achieve is validate passwords fields in my form and in case success redirect toward another component ('/customers') or in case that passwords are not the same we should do nothing and give a chance to the user to retype proper passwords again.

RegistrationComponent.ts

```<code>
@Component({
  selector: 'app-registration',
  templateUrl: './registration.component.html',
  styleUrls: ['./registration.component.css']
})
export class RegistrationComponent implements OnInit {

  registerForm: FormGroup;
  submitted = false;
  email$: Observable<string>;

  constructor(private formBuilder: FormBuilder, private customerService: CustomerService, private router: Router) {
  }

  ngOnInit() {

    this.registerForm = this.formBuilder.group({
      username: ['', Validators.required],
      email: ['', Validators.required],
      name: ['', Validators.required],
      surname: ['', Validators.required],
      phoneNumber: ['', Validators.required],
      nip: ['', Validators.required],
      password: ['', Validators.required],
      confirmPassword: ['', Validators.required],
    }, {
      validator: MustMatch('password', 'confirmPassword')
    });
  }

  get form() {
    return this.registerForm.controls;
  }

  onSubmit() {
    this.submitted = true;

    const registeredCustomer: RegistrationForm = {

      username: this.registerForm.controls.username.value,
      email: this.registerForm.controls.email.value,
      name: this.registerForm.controls.name.value,
      surname: this.registerForm.controls.surname.value,
      phoneNumber: this.registerForm.controls.phoneNumber.value,
      password: this.registerForm.controls.password.value,
      confirmPassword: this.registerForm.controls.confirmPassword.value,

    };

    this.email$ = this.customerService
    .register(registeredCustomer)
    .pipe(map(customer => customer.email));

    if (this.registerForm.invalid) {
      return;
    } else {
      setTimeout(() => this.router.navigate((['/customers'])), 5000);
    }

    alert('User successfully registered' + JSON.stringify(this.registerForm.value));

  }

}

</code>```

RegistrationComponent.html

```<code><div class="jumbotron">
  <div class="container">
    <div class="row">
      <div class="col-md-6 offset-md-3">
        <h3>Fill in the form below to complete the registration process </h3>
        <form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
          <div class="form-group">
            <label>Username</label>
            <input type="text" formControlName="username" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.username.errors }" />
            <div *ngIf="submitted && form.username.errors" class="invalid-feedback">
              <div *ngIf="form.username.errors.required">Username is required</div>
            </div>
          </div>
          <div class="form-group">
            <label>Name</label>
            <input type="text" formControlName="name" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.name.errors }" />
            <div *ngIf="submitted && form.name.errors" class="invalid-feedback">
              <div *ngIf="form.name.errors.required">Customer name is required</div>
            </div>
          </div>
          <div class="form-group">
            <label>Surname</label>
            <input type="text" formControlName="surname" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.surname.errors }" />
            <div *ngIf="submitted && form.surname.errors" class="invalid-feedback">
              <div *ngIf="form.surname.errors.required">Customer surname is required</div>
            </div>
          </div>
          <div class="form-group">
            <label>Phone Number</label>
            <input type="text" formControlName="phoneNumber" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.phoneNumber.errors }" />
            <div *ngIf="submitted && form.phoneNumber.errors" class="invalid-feedback">
              <div *ngIf="form.phoneNumber.errors.required">Phone number is required</div>
            </div>
          </div>
          <div class="form-group">
            <label>Email</label>
            <input type="text" formControlName="email" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.email.errors }" />
            <div *ngIf="submitted && form.email.errors" class="invalid-feedback">
              <div *ngIf="form.email.errors.required">Email is required</div>
              <div *ngIf="form.email.errors.email">Email must be a valid email address</div>
            </div>
          </div>
          <div class="form-group">
            <label>Password</label>
            <input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.password.errors }" />
            <div *ngIf="submitted && form.password.errors" class="invalid-feedback">
              <div *ngIf="form.password.errors.required">Password is required</div>
              <div *ngIf="form.password.errors.minlength">Password must be at least 6 characters</div>
            </div>
          </div>
          <div class="form-group">
            <label>Confirm Password</label>
            <input type="password" formControlName="confirmPassword" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.confirmPassword.errors }" />
            <div *ngIf="submitted && form.confirmPassword.errors" class="invalid-feedback">
              <div *ngIf="form.confirmPassword.errors.required">Confirm Password is required</div>
              <div *ngIf="form.confirmPassword.errors.mustMatch">Passwords must match</div>
            </div>
          </div>
          <div class="form-group">
            <button class="btn btn-primary">Register</button>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>

</code>```

I was based on this tutorial: Registration tutorial

but after small modification, my current solution is not working properly.

I was trying to replace this

```<code>    setTimeout(() => this.router.navigate((['/customers'])), 5000);
</code>```

infront of:

```<code>    if (this.registerForm.invalid) {
      return;
    }
</code>```

and checking if boolean value submitted = false but it didn't yield the desired result.

Thank you in advance for all your help.

Edit: Stackblitz link for application.

component

stackblitz editor

答:
We've been working at work on a library to handle forms easily and with also more type safety (for both TS and HTML!). This library is called ngx-sub-form and you can find it here: https://github.com/cloudnc/ngx-sub-form

Using ngx-sub-form, I've made a demo of your app that you can try here:

 https://stackblitz.com/edit/angular-genpiv

Now, some explanations.

First, we want to define a proper interface for your form (type safety for the win!):

```<code>export interface RegistrationForm {
  username: string;
  email: string;
  name: string;
  surname: string;
  phoneNumber: string;
  nip: string;
  password: string;
  confirmPassword: string;
}
</code>```

Then we create all the components we need for the app:

- app/app.component.ts

- app/registration/registration.component.ts

- app/registration/registration-form/registration-form.component.ts

- app/customers.component.ts

Now we need to define the routing for our app. Our app.module.ts should look like the following:

```<code>const ROUTES: Routes = [
  {
    path: '',
    redirectTo: '/registration',
    pathMatch: 'full'
  },
  {
    path: 'registration',
    component: RegistrationComponent
  },
  {
    path: 'customers',
    component: CustomersComponent
  },
];

@NgModule({
  imports: [BrowserModule, ReactiveFormsModule, RouterModule.forRoot(ROUTES)],
  declarations: [AppComponent, RegistrationFormComponent, RegistrationComponent, CustomersComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }
</code>```

And app.component.html should simply be <router-outlet></router-outlet>.

RegistrationComponent will act as a smart component. It will inject the router and just wait for the form to be sent. That component doesn't want to be aware of the form itself, just the object that has been sent.

```<code>@Component({
  selector: 'app-registration',
  templateUrl: './registration.component.html',
  styleUrls: ['./registration.component.css']
})
export class RegistrationComponent {
  constructor(private router: Router) {}

  public register(registrationForm: RegistrationForm): void {
    // here you probably want to inject a `RegistrationService` instead of the `Router`
    // and call a method that will make an XHR call to your backend and on success
    // would do that `navigate` from the service too
    // for the sake of simplicity here I'm just doing the navigate directly
    this.router.navigate(['/customers']);
  }
}
</code>```

And its HTML:

```<code><app-registration-form (register)="register($event)"></app-registration-form>
</code>```

RegistrationFormComponent will be the component responsible to handle the form. That component is the only one that needs to use ngx-sub-form library.

```<code>@Component({
  selector: 'app-registration-form',
  templateUrl: './registration-form.component.html',
  styleUrls: ['./registration-form.component.css']
})
export class RegistrationFormComponent extends NgxSubFormComponent<RegistrationForm> {
  @Output() register: EventEmitter<RegistrationForm> = new EventEmitter();

  protected getFormControls(): Controls<RegistrationForm> {
    return {
      username: new FormControl(null, [Validators.required]),
      email: new FormControl(null, [Validators.required]),
      name: new FormControl(null, [Validators.required]),
      surname: new FormControl(null, [Validators.required]),
      phoneNumber: new FormControl(null, [Validators.required]),
      nip: new FormControl(null, [Validators.required]),
      password: new FormControl(null, [Validators.required]),
      confirmPassword: new FormControl(null, [Validators.required]),
    }
  }

  protected getFormGroupControlOptions(): FormGroupOptions<RegistrationForm> {
    return {
      validators: [
        formGroup => {
          if (formGroup.value.password !== formGroup.value.confirmPassword) {
            return {
              passwordsMustMatch: true,
            };
          }

          return null;
        },
      ],
    };
  }

  public onSubmit(): void {
    this.register.emit(this.formGroupValues)
  }
}
</code>```

Things to notice here:

export class RegistrationFormComponent extends NgxSubFormComponent<RegistrationForm> we're extending NgxSubFormComponent and we pass our form interface. That will provide us a lot utilities and also some type safety

The method getFormControls expects you to basically provide an object to create your form. I think it's self explanatory because it looks like the object you'd pass when creating a FormGroup

getFormGroupControlOptions is a hook provided by NgxSubFormComponent that allows you to set validators or asyncValidators at the FormGroup level

Finally, the onSubmit method is the one that'll be called when the user clicks on the Register button (once the form is fully valid)

Now, the last missing piece is the form HTML (for simplicity I'll only display in the response the first field and the password check because everything in between is pretty much the same)

```<code><div class="jumbotron">
  <div class="container">
    <div class="row">
      <div class="col-md-6 offset-md-3">
        <h3>Fill in the form below to complete the registration process</h3>
        <form [formGroup]="formGroup" (ngSubmit)="onSubmit()">
          <div class="form-group">
            <label>Username</label>
            <input type="text" [formControlName]="formControlNames.username" class="form-control" [ngClass]="{ 'is-invalid': formGroupErrors?.username }" />
            <div *ngIf="formGroupErrors && formGroupControls.username.touched" class="invalid-feedback">
              <div *ngIf="formGroupErrors?.username?.required">Username is required</div>
            </div>
          </div>

          ...

          <div class="form-group">
            <label>Confirm Password</label>
            <input type="text" [formControlName]="formControlNames.confirmPassword" class="form-control" [ngClass]="{ 'is-invalid': formGroupErrors?.confirmPassword }" />
            <div *ngIf="formGroupErrors && formGroupControls.confirmPassword.touched" class="invalid-feedback">
              <div *ngIf="formGroupErrors?.confirmPassword?.required">Confirm Password is required</div>
              <div *ngIf="formGroupErrors?.formGroup?.passwordsMustMatch">Passwords must match</div>
            </div>
          </div>

          <div class="form-group">
            <button class="btn btn-primary" [disabled]="formGroup.invalid">Register</button>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>
</code>```

Things to notice from the HTML:

<form [formGroup]="formGroup" we haven't defined the formGroup ourselves. It's been created by NgxSubFormComponent

<input type="text" [formControlName]="formControlNames.username" the formControlNames property is also defined by NgxSubFormComponent and its main purpose is to bring some type safety! If you try to put formControlNames.random you'll get a run time error, but also a Typescript error when compiling with AOT!

 the property formGroupErrors is also provided by NgxSubFormComponent and gives you access to the form errors. Best part is that it works with nested sub forms and is also type safe! Even though here we don't have any sub form, I invite you to check the Github page of ngx-sub-form to learn more about that

The app is now fully ready and has a lot of type safety! Any refactor impacting the main interface will also require you to update the form (TS + HTML) otherwise Typescript will throw errors around.

Here's how it looks like:

Then once it's valid:

And then when we click on register:

Don't forget to check out the live example here: https://stackblitz.com/edit/angular-genpiv

Edit:

If you want to go further, I've just published a blog post to explain a lot of things about forms and ngx-sub-form here https://dev.to/maxime1992/building-scalable-robust-and-type-safe-forms-with-angular-3nf9

Body:
Today, I encountered a problem with angular routing after successful validation of Angular reactive form. All I want to achieve is validate passwords fields in my form and in case success redirect toward another component ('/customers') or in case that passwords are not the same we should do nothing and give a chance to the user to retype proper passwords again.

RegistrationComponent.ts

@Component({
  selector: 'app-registration',
  templateUrl: './registration.component.html',
  styleUrls: ['./registration.component.css']
})
export class RegistrationComponent implements OnInit {

  registerForm: FormGroup;
  submitted = false;
  email$: Observable<string>;

  constructor(private formBuilder: FormBuilder, private customerService: CustomerService, private router: Router) {
  }

  ngOnInit() {

    this.registerForm = this.formBuilder.group({
      username: ['', Validators.required],
      email: ['', Validators.required],
      name: ['', Validators.required],
      surname: ['', Validators.required],
      phoneNumber: ['', Validators.required],
      nip: ['', Validators.required],
      password: ['', Validators.required],
      confirmPassword: ['', Validators.required],
    }, {
      validator: MustMatch('password', 'confirmPassword')
    });
  }

  get form() {
    return this.registerForm.controls;
  }

  onSubmit() {
    this.submitted = true;

    const registeredCustomer: RegistrationForm = {

      username: this.registerForm.controls.username.value,
      email: this.registerForm.controls.email.value,
      name: this.registerForm.controls.name.value,
      surname: this.registerForm.controls.surname.value,
      phoneNumber: this.registerForm.controls.phoneNumber.value,
      password: this.registerForm.controls.password.value,
      confirmPassword: this.registerForm.controls.confirmPassword.value,

    };

    this.email$ = this.customerService
    .register(registeredCustomer)
    .pipe(map(customer => customer.email));

    if (this.registerForm.invalid) {
      return;
    } else {
      setTimeout(() => this.router.navigate((['/customers'])), 5000);
    }

    alert('User successfully registered' + JSON.stringify(this.registerForm.value));

  }

}

RegistrationComponent.html

Fill in the form below to complete the registration process

        <form [formGroup]="registerForm" (ngSubmit)="onSubmit()">

            Username
            <input type="text" formControlName="username" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.username.errors }" />

Username is required

            Name
            <input type="text" formControlName="name" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.name.errors }" />

Customer name is required

            Surname
            <input type="text" formControlName="surname" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.surname.errors }" />

Customer surname is required

            Phone Number
            <input type="text" formControlName="phoneNumber" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.phoneNumber.errors }" />

Phone number is required

            Email
            <input type="text" formControlName="email" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.email.errors }" />

Email is required

Email must be a valid email address

            Password
            <input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.password.errors }" />

Password is required

Password must be at least 6 characters

            Confirm Password
            <input type="password" formControlName="confirmPassword" class="form-control" [ngClass]="{ 'is-invalid': submitted && form.confirmPassword.errors }" />

Confirm Password is required

Passwords must match

            <button class="btn btn-primary">Register</button>

        </form>

I was based on this tutorial: Registration tutorial

but after small modification, my current solution is not working properly.

I was trying to replace this

    setTimeout(() => this.router.navigate((['/customers'])), 5000);

infront of:

    if (this.registerForm.invalid) {
      return;
    }

and checking if boolean value submitted = false but it didn't yield the desired result.

Thank you in advance for all your help.

Edit: Stackblitz link for application.

component

stackblitz editor

Body:
We've been working at work on a library to handle forms easily and with also more type safety (for both TS and HTML!). This library is called ngx-sub-form and you can find it here: https://github.com/cloudnc/ngx-sub-form

Using ngx-sub-form, I've made a demo of your app that you can try here:

 https://stackblitz.com/edit/angular-genpiv

Now, some explanations.

First, we want to define a proper interface for your form (type safety for the win!):

export interface RegistrationForm {
  username: string;
  email: string;
  name: string;
  surname: string;
  phoneNumber: string;
  nip: string;
  password: string;
  confirmPassword: string;
}

Then we create all the components we need for the app:

- app/app.component.ts

- app/registration/registration.component.ts

- app/registration/registration-form/registration-form.component.ts

- app/customers.component.ts

Now we need to define the routing for our app. Our app.module.ts should look like the following:

const ROUTES: Routes = [
  {
    path: '',
    redirectTo: '/registration',
    pathMatch: 'full'
  },
  {
    path: 'registration',
    component: RegistrationComponent
  },
  {
    path: 'customers',
    component: CustomersComponent
  },
];

@NgModule({
  imports: [BrowserModule, ReactiveFormsModule, RouterModule.forRoot(ROUTES)],
  declarations: [AppComponent, RegistrationFormComponent, RegistrationComponent, CustomersComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }

And app.component.html should simply be <router-outlet></router-outlet>.

RegistrationComponent will act as a smart component. It will inject the router and just wait for the form to be sent. That component doesn't want to be aware of the form itself, just the object that has been sent.

@Component({
  selector: 'app-registration',
  templateUrl: './registration.component.html',
  styleUrls: ['./registration.component.css']
})
export class RegistrationComponent {
  constructor(private router: Router) {}

  public register(registrationForm: RegistrationForm): void {
    // here you probably want to inject a `RegistrationService` instead of the `Router`
    // and call a method that will make an XHR call to your backend and on success
    // would do that `navigate` from the service too
    // for the sake of simplicity here I'm just doing the navigate directly
    this.router.navigate(['/customers']);
  }
}

And its HTML:

<app-registration-form (register)="register($event)"></app-registration-form>

RegistrationFormComponent will be the component responsible to handle the form. That component is the only one that needs to use ngx-sub-form library.

@Component({
  selector: 'app-registration-form',
  templateUrl: './registration-form.component.html',
  styleUrls: ['./registration-form.component.css']
})
export class RegistrationFormComponent extends NgxSubFormComponent<RegistrationForm> {
  @Output() register: EventEmitter<RegistrationForm> = new EventEmitter();

  protected getFormControls(): Controls<RegistrationForm> {
    return {
      username: new FormControl(null, [Validators.required]),
      email: new FormControl(null, [Validators.required]),
      name: new FormControl(null, [Validators.required]),
      surname: new FormControl(null, [Validators.required]),
      phoneNumber: new FormControl(null, [Validators.required]),
      nip: new FormControl(null, [Validators.required]),
      password: new FormControl(null, [Validators.required]),
      confirmPassword: new FormControl(null, [Validators.required]),
    }
  }

  protected getFormGroupControlOptions(): FormGroupOptions<RegistrationForm> {
    return {
      validators: [
        formGroup => {
          if (formGroup.value.password !== formGroup.value.confirmPassword) {
            return {
              passwordsMustMatch: true,
            };
          }

          return null;
        },
      ],
    };
  }

  public onSubmit(): void {
    this.register.emit(this.formGroupValues)
  }
}

Things to notice here:

export class RegistrationFormComponent extends NgxSubFormComponent<RegistrationForm> we're extending NgxSubFormComponent and we pass our form interface. That will provide us a lot utilities and also some type safety

The method getFormControls expects you to basically provide an object to create your form. I think it's self explanatory because it looks like the object you'd pass when creating a FormGroup

getFormGroupControlOptions is a hook provided by NgxSubFormComponent that allows you to set validators or asyncValidators at the FormGroup level

Finally, the onSubmit method is the one that'll be called when the user clicks on the Register button (once the form is fully valid)

Now, the last missing piece is the form HTML (for simplicity I'll only display in the response the first field and the password check because everything in between is pretty much the same)

<div class="jumbotron">
  <div class="container">
    <div class="row">
      <div class="col-md-6 offset-md-3">
        <h3>Fill in the form below to complete the registration process</h3>
        <form [formGroup]="formGroup" (ngSubmit)="onSubmit()">
          <div class="form-group">
            <label>Username</label>
            <input type="text" [formControlName]="formControlNames.username" class="form-control" [ngClass]="{ 'is-invalid': formGroupErrors?.username }" />
            <div *ngIf="formGroupErrors && formGroupControls.username.touched" class="invalid-feedback">
              <div *ngIf="formGroupErrors?.username?.required">Username is required</div>
            </div>
          </div>

          ...

          <div class="form-group">
            <label>Confirm Password</label>
            <input type="text" [formControlName]="formControlNames.confirmPassword" class="form-control" [ngClass]="{ 'is-invalid': formGroupErrors?.confirmPassword }" />
            <div *ngIf="formGroupErrors && formGroupControls.confirmPassword.touched" class="invalid-feedback">
              <div *ngIf="formGroupErrors?.confirmPassword?.required">Confirm Password is required</div>
              <div *ngIf="formGroupErrors?.formGroup?.passwordsMustMatch">Passwords must match</div>
            </div>
          </div>

          <div class="form-group">
            <button class="btn btn-primary" [disabled]="formGroup.invalid">Register</button>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>

Things to notice from the HTML:

<form [formGroup]="formGroup" we haven't defined the formGroup ourselves. It's been created by NgxSubFormComponent

<input type="text" [formControlName]="formControlNames.username" the formControlNames property is also defined by NgxSubFormComponent and its main purpose is to bring some type safety! If you try to put formControlNames.random you'll get a run time error, but also a Typescript error when compiling with AOT!

<div *ngIf="formGroupErrors?.username?.required"> the property formGroupErrors is also provided by NgxSubFormComponent and gives you access to the form errors. Best part is that it works with nested sub forms and is also type safe! Even though here we don't have any sub form, I invite you to check the Github page of ngx-sub-form to learn more about that

The app is now fully ready and has a lot of type safety! Any refactor impacting the main interface will also require you to update the form (TS + HTML) otherwise Typescript will throw errors around.

Here's how it looks like:

Then once it's valid:

And then when we click on register:

Don't forget to check out the live example here: https://stackblitz.com/edit/angular-genpiv

Edit:

If you want to go further, I've just published a blog post to explain a lot of things about forms and ngx-sub-form here https://dev.to/maxime1992/building-scalable-robust-and-type-safe-forms-with-angular-3nf9


问:
how to get multiple option from select without pressing control key?
I have 2 'select' in my html code and from first select, i want to choose only one option and from second select i want to choose multiple options. I have written code in jquery to get multiple options from select.

JQuery

```<code>$('option').mousedown(function(e) {
        e.preventDefault();
        $(this).prop('selected', !$(this).prop('selected'));
        return false;
    });
</code>```

and this code is working perfect, but the problem is my second select is working fine but in my first select i am not able to choose any option and i just want to get only one option from first select.

HTML

```<code>        <div class="form-group">
            <div class="col-sm-3">
                <label style="width: 100%;" class="control-label"
                    th:text="#{CLONE.MASTERID}"></label>
            </div>
            <div class="col-sm-9">
                <select class="form-control" id="cloneMasterIds">
                    <option value="">Select Master Device Id</option>
                    <option th:each="master : ${masterIds}" th:value="${master.value}"
                        th:utext="${master.value}">Wireframe</option>
                </select>
                <p class="field-error hidden-true"
                    id="SerialNumber-Error" th:text="#{ERROR.CLONE.MASTERID}"></p>
            </div>
        </div>

        <!-- Child IDs -->
        <div class="form-group">
            <div class="col-sm-3">
                <label style="width: 100%;" class="control-label"
                    th:text="#{CLONE.CHILDID}"></label>
            </div>
            <div class="col-sm-9">

                <select class="form-control select-checkbox" id="cloneChildIds"
                    multiple="multiple">
                    <option th:each="child : ${childIds}" th:value="${child.value}"
                        th:utext="${child.value}">Wireframe</option>
                </select>
                <p class="field-error hidden-true"
                    id="SerialNumber-Error" th:text="#{ERROR.CLONE.CHILDID}"></p>
            </div>
        </div>
</code>```

答:
Select the second select statement by id. Handle the mousedown and mousemove events:

```<code>$("#cloneChildIds").mousedown(function(e){
    e.preventDefault();

    var select = this;
    var scroll = select.scrollTop;

    e.target.selected = !e.target.selected;

    setTimeout(() => select.scrollTop = scroll, 0);
    $(select).focus();
}).mousemove(e => e.preventDefault());
</code>```

Body:
I have 2 'select' in my html code and from first select, i want to choose only one option and from second select i want to choose multiple options. I have written code in jquery to get multiple options from select.

JQuery

$('option').mousedown(function(e) {
        e.preventDefault();
        $(this).prop('selected', !$(this).prop('selected'));
        return false;
    });

and this code is working perfect, but the problem is my second select is working fine but in my first select i am not able to choose any option and i just want to get only one option from first select.

HTML

                <select class="form-control" id="cloneMasterIds">
                    <option value="">Select Master Device Id</option>
                    <option th:each="master : ${masterIds}" th:value="${master.value}"
                        th:utext="${master.value}">Wireframe</option>
                </select>

                <select class="form-control select-checkbox" id="cloneChildIds"
                    multiple="multiple">
                    <option th:each="child : ${childIds}" th:value="${child.value}"
                        th:utext="${child.value}">Wireframe</option>
                </select>

Body:
Select the second select statement by id. Handle the mousedown and mousemove events:

$("#cloneChildIds").mousedown(function(e){
    e.preventDefault();

    var select = this;
    var scroll = select.scrollTop;

    e.target.selected = !e.target.selected;

    setTimeout(() => select.scrollTop = scroll, 0);
    $(select).focus();
}).mousemove(e => e.preventDefault());


问:
call second function only after first function has been called - react native
I just started with react native and I'm pulling data from an API. The first function calls data successfully and the second function will need a variable from the first function before it can make a successful call. I'm trying to make the second API call successful but it fails

```<code>componentDidMount = async () => {
const communities = await API.getUserCommunityInfo(userId);
console.log(communities)
this.setState({userCommunities: communities, communityMemberId: communities[0].member.id, communityId: communities[0].community.id},
console.log(this.state),
this.getGroups()
)

}
</code>```

SECOND FUNCTION

```<code>getGroups = async () => {
const groups = await API.getGroups(communityMemberId)
this.setState({userGroups: groups ,showLoader: false})
}
</code>```

The second function will need a state from the first function communityMemberId before it makes a successful call

答:
You can check if the first function's response and if it success then call second function.</p>

```<code>getGroups = async () => {
const groups = await API.getGroups(communityMemberId)
this.setState({userGroups: groups ,showLoader: false})
   if(succees){
    //call second function
    this.secondFunction()
   }
}
</code>```

Body:
I just started with react native and I'm pulling data from an API. The first function calls data successfully and the second function will need a variable from the first function before it can make a successful call. I'm trying to make the second API call successful but it fails

componentDidMount = async () => {
const communities = await API.getUserCommunityInfo(userId);
console.log(communities)
this.setState({userCommunities: communities, communityMemberId: communities[0].member.id, communityId: communities[0].community.id},
console.log(this.state),
this.getGroups()
)

}

SECOND FUNCTION

getGroups = async () => {
const groups = await API.getGroups(communityMemberId)
this.setState({userGroups: groups ,showLoader: false})
}

The second function will need a state from the first function communityMemberId before it makes a successful call

Body:
You can check if the first function's response and if it success then call second function.

getGroups = async () => {
const groups = await API.getGroups(communityMemberId)
this.setState({userGroups: groups ,showLoader: false})
   if(succees){
    //call second function
    this.secondFunction()
   }
}


答:
Just add a property into a second function or add a callback function after setState is finished.</p>

```<code>componentDidMount = async () => {
    const communities = await API.getUserCommunityInfo(userId);
    console.log(communities)
    this.setState({
       userCommunities: communities,
       communityMemberId: communities[0].member.id,
       communityId: communities[0].community.id
    }, () => {
        this.getGroups(this.state.communityMemberId); // callback function after the state is updated
    });
    // or
    this.getGroups(communities[0].member.id); // this is faster since user don't wait state to be updated
}

getGroups = async (communityMemberId) => {
    const groups = await API.getGroups(communityMemberId)
    this.setState({userGroups: groups ,showLoader: false})
}
</code>```

Title: call second function only after first function has been called - react native

Body:
Just add a property into a second function or add a callback function after setState is finished.

componentDidMount = async () => {
    const communities = await API.getUserCommunityInfo(userId);
    console.log(communities)
    this.setState({
       userCommunities: communities,
       communityMemberId: communities[0].member.id,
       communityId: communities[0].community.id
    }, () => {
        this.getGroups(this.state.communityMemberId); // callback function after the state is updated
    });
    // or
    this.getGroups(communities[0].member.id); // this is faster since user don't wait state to be updated
}

getGroups = async (communityMemberId) => {
    const groups = await API.getGroups(communityMemberId)
    this.setState({userGroups: groups ,showLoader: false})
}


问:
In JUnit 5, how to run code before all tests
The @BeforeAll annotation marks a method to run before all tests in a class.

http://junit.org/junit5/docs/current/user-guide/#writing-tests-annotations

But is there a way to run some code before all tests, in all classes?

I want to ensure that tests use a certain set of database connections, and the global one-time setup of these connections must occur before running any tests.

答:
Above advises do not work for me, so I solved this problem like this:

Add to your Base abstract class (I mean abstract class where you initialize your driver in setUpDriver() method) this part of code:

```<code>private static boolean started = false;
static{
    if (!started) {
        started = true;
        try {
            setUpDriver();  //method where you initialize your driver
        } catch (MalformedURLException e) {
        }
    }
}
</code>```

And now, if your test classes will extends from Base abstract class -> setUpDriver() method will be executed before first @Test only ONE time per project run.

Body:
Above advises do not work for me, so I solved this problem like this:

Add to your Base abstract class (I mean abstract class where you initialize your driver in setUpDriver() method) this part of code:

private static boolean started = false;
static{
    if (!started) {
        started = true;
        try {
            setUpDriver();  //method where you initialize your driver
        } catch (MalformedURLException e) {
        }
    }
}

And now, if your test classes will extends from Base abstract class -> setUpDriver() method will be executed before first @Test only ONE time per project run.


问:
Count Instances of Class
I am looking for a way to programatically get the number of instances of a certain class type in .NET and Java.

Say for example I have class Foo.  I want to be able to, in the same process, get a current count of all instance of Foo.

However I cannot modify Foo, so a static int with counting is out.  Also I cannot just add all instances I make to some static list and count that.  I want to be able to just say:

```<code>System.GC.numberOf< Foo >()
</code>```

or something.

I was looking through the garbage collectors but I could not find any relevant methods.

答:
Do you have control of how the Java VM is being run? If so, you can write a quick and dirty debugger agent...  http://download.oracle.com/javase/1.5.0/docs/guide/jvmti/jvmti.html#writingAgents

See the events "VM Object Allocation" and "Object Free"

Title: Count Instances of Class

Body:
I am looking for a way to programatically get the number of instances of a certain class type in .NET and Java.

Say for example I have class Foo.  I want to be able to, in the same process, get a current count of all instance of Foo.

However I cannot modify Foo, so a static int with counting is out.  Also I cannot just add all instances I make to some static list and count that.  I want to be able to just say:

System.GC.numberOf< Foo >()

or something.

I was looking through the garbage collectors but I could not find any relevant methods.


问:
realloc not allocating memory for next struct
I need to make an array of structs dynamically and I don't know the size when executing the malloc command. So I thought I could use realloc every time I need another struct! For example this code:

main:

```<code>    int main(void) {

    flights *flight_list = NULL;
    int numFlights = 0;

    numFlights = load_flights(&flight_list);

    /* output flights. Problem: Only first flight is there, the second is not allocated! */
</code>```

Here's the function:

```<code>short load_flights(flights **flight_list) {

    flight_list[0] = calloc(1, sizeof(flights));
    flight_list[0]->price = 69;

    flight_list[0] = realloc(*flight_list, sizeof(flights)*2);
    flight_list[1]->price = 70;

    return 2; //num of flights-structs
</code>```

The problem is, that actually 2 elements should be created, but only 1 element is there - check this debugging screenshot:

As you can see, flight_list[0] is there, but flight_list[1] not! But realloc should do the job?

Am I understanding anything wrong?

答:
Your flight_list is an array of pointers to pointers of flights.

With flight_list[0] = realloc(*flight_list, sizeof(flights)*2); you allocate space for two flights to the item flight_list[0], but flight_list itself remains unchanged. In fact, there is no code that allocates any space for flight_list at all, but maybe you just left out this code in your example.

If the realloc line of code is what you wanted, you should watch these memory locations in the debugger: flight_list[0][0] for the first flight, and flight_list[0][1] for the second.

Body:
I need to make an array of structs dynamically and I don't know the size when executing the malloc command. So I thought I could use realloc every time I need another struct! For example this code:

main:

    int main(void) {

    flights *flight_list = NULL;
    int numFlights = 0;

    numFlights = load_flights(&flight_list);

    /* output flights. Problem: Only first flight is there, the second is not allocated! */

Here's the function:

short load_flights(flights **flight_list) {

    flight_list[0] = calloc(1, sizeof(flights));
    flight_list[0]->price = 69;

    flight_list[0] = realloc(*flight_list, sizeof(flights)*2);
    flight_list[1]->price = 70;

    return 2; //num of flights-structs

The problem is, that actually 2 elements should be created, but only 1 element is there - check this debugging screenshot:

As you can see, flight_list[0] is there, but flight_list[1] not! But realloc should do the job?

Am I understanding anything wrong?


问:
Images folder lost after Elastic Bean Stalk restarted. Any way to restore them?
I had recently faced some issue with the application (Django Application) because of which I had to restart my Elastic Bean Stalk. Once the application has been restarted I lost my data which was residing in the upload folder of the application directory.

I have no idea how to get them back.

Is there any possibility that I can recover them. Any file recovery software can help?

答:
Your upload folder might have been mounted to ephemeral volume which is located on physical EC2 machine. If you want to make data resistant to shut down, use EBS volume instead.

Please find more details here:
https://aws.amazon.com/blogs/devops/customize-ephemeral-and-ebs-volumes-in-elastic-beanstalk-environments/


问:
How to change Postman current variable value in collection scope?
I have variable "TOKEN" in my collection scope. I try to set the value using Tests scripts when do a request. But the variable not changed.

So, I try to use environment scope variable. And It works.

Why It's doesn't work when in collection scope? I had read about postman variable scope here and understand it well.

Here're some screenshots:

1. First, I call login endpoint.

Below is the console result. Nothing wrong.

Until I try to get all users endpoint that required token in request header. The status is 401 because the token is null. If the token is not null, then it will return 200:

It's gracefully working when I add "TOKEN" variable to environment. Switch to No Environment again will result 401 status code:

答:
You can now use:

```<code>pm.collectionVariables.set("variable_key", "variable_value");
</code>```

In my original answer in June 2019, I wrote that collection variables are not editable through scripts, and can only be changed manually. As noted, this is no longer the case. . . .*

Body:
You can now use:

pm.collectionVariables.set("variable_key", "variable_value");

In my original answer in June 2019, I wrote that collection variables are not editable through scripts, and can only be changed manually. As noted, this is no longer the case. . . .*


问:
How to add a animation to a Player?
I'm currently making a shoot em up in monogame.

I've managed to make a constantly looping animation with my sprite but the problem is that I now don't know how to insert my animated sprite to myPlayer.

I don't want any commands only a constantly looped animation attached to myPlayer. I'm a beginner to programming so help is much appreciated.

This project is due soon so would love some help.

```<code>Game1:
        Texture2D myPlayerAnim;
        Rectangle myDestRect;
        Rectangle mySourceRect;
        Texture2D myEnemyAnim;
        Rectangle myEnemyDestRect;
        Rectangle myEnemySourceRect;
        float myElapsed;
        float myDelay = 100f;
        int myFrames = 0;

Initialize:
            myDestRect = new Rectangle(0, 0, 512, 512);
            myEnemyDestRect = new Rectangle(0, 0, 808, 608);

LoadContent:

            myPlayerAnim = Content.Load<Texture2D>("SpriteSheetPlayerAnim");
            myEnemyAnim = Content.Load<Texture2D>("SpriteSheetEnemyAnim");

Update:
            myElapsed += (float)aGameTime.ElapsedGameTime.TotalMilliseconds;

            if (myElapsed >= myDelay)
            {
                if (myFrames >= 3)
                {
                    myFrames = 0;
                }
                else
                {
                    myFrames++;
                }
                myElapsed = 0;
            }

            mySourceRect = new Rectangle(512 * myFrames, 0, 512, 512);
            myEnemySourceRect = new Rectangle(808 * myFrames, 0, 808, 608);

Draw:

            mySpriteBatch.Draw(myPlayerAnim, myDestRect , mySourceRect,
            Color.White);
            mySpriteBatch.Draw(myEnemyAnim, myEnemyDestRect, myEnemySourceRect,
            Color.White);
</code>```

Draw currently only draws out the animation because it's not attached to anything.

currently myPlayer only has a single png attached and not my animation.

```<code>Draw:
myPlayer = new Player(TextureLibrary.GetTexture("player"), myPlayerPos, 200, new Vector2(.3f, .3f), 0, Color.White, 1000, 1);
</code>```

答:
Based on your code you have given. I think you just need to change some things.

First, use the SpriteSheetPlayerAnim as the texture of your player directly instead of using player texture.

Then move the code of Update and Draw of player's animation to Update and Draw of Player class.

They will be like this:

```<code>public class Player
{
    //Default constructor
    public Player()
    {
        //default values for your player//for example only
        //this.hp = 100;
        //this.mp = 20;
    }

    //Constructor
    public Player(GameTime myelapsedGameTime, Texture2D texPlayer, Vector2 playerPosition, int something, Vector2 vector2ForSomething, int intFST, Color playerColor, ...)
    {
        //initialise player's attributes

    }

    public override Update(GameTime gameTime)
    {
        if (myElapsed >= myDelay)
        {
            if (myFrames >= 3)
            {
                myFrames = 0;
            }
            else
            {
                myFrames++;
            }
            myElapsed = 0;
        }
    }

    public override Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(myPlayerAnim, myDestRect , mySourceRect,
            Color.White);//for example
    }
}
</code>```

Then in your Game1 class:

```<code>public class Game1 : Game
{
    Player player;
    GameTime myElapsed;

    public Game1()
    {
        //
    }

    protected override void LoadContent()
    {
        //Load your animated sprite here
        myPlayerAnim = Content.Load<Texture2D>("SpriteSheetPlayerAnim");

        player = new Player(myElapsed, myPlayerAnim, ...);//constructor with attributes here or whatever you want
    }

    protected override void Update(GameTime gameTime)
    {
        myElapsed += (float)aGameTime.ElapsedGameTime.TotalMilliseconds;
        player.Update(gameTime);
    }

    protected override void Draw(SpriteBatch spriteBatch)
    {
        player.Draw(spriteBatch);
    }
}
</code>```

Hope this helps!

Title: How to add a animation to a Player?

Body:
I'm currently making a shoot em up in monogame.

I've managed to make a constantly looping animation with my sprite but the problem is that I now don't know how to insert my animated sprite to myPlayer.

I don't want any commands only a constantly looped animation attached to myPlayer. I'm a beginner to programming so help is much appreciated.

This project is due soon so would love some help.

Game1:
        Texture2D myPlayerAnim;
        Rectangle myDestRect;
        Rectangle mySourceRect;
        Texture2D myEnemyAnim;
        Rectangle myEnemyDestRect;
        Rectangle myEnemySourceRect;
        float myElapsed;
        float myDelay = 100f;
        int myFrames = 0;

Initialize:
            myDestRect = new Rectangle(0, 0, 512, 512);
            myEnemyDestRect = new Rectangle(0, 0, 808, 608);

LoadContent:

            myPlayerAnim = Content.Load<Texture2D>("SpriteSheetPlayerAnim");
            myEnemyAnim = Content.Load<Texture2D>("SpriteSheetEnemyAnim");

Update:
            myElapsed += (float)aGameTime.ElapsedGameTime.TotalMilliseconds;

            if (myElapsed >= myDelay)
            {
                if (myFrames >= 3)
                {
                    myFrames = 0;
                }
                else
                {
                    myFrames++;
                }
                myElapsed = 0;
            }

            mySourceRect = new Rectangle(512 * myFrames, 0, 512, 512);
            myEnemySourceRect = new Rectangle(808 * myFrames, 0, 808, 608);

Draw:

            mySpriteBatch.Draw(myPlayerAnim, myDestRect , mySourceRect,
            Color.White);
            mySpriteBatch.Draw(myEnemyAnim, myEnemyDestRect, myEnemySourceRect,
            Color.White);

Draw currently only draws out the animation because it's not attached to anything.

currently myPlayer only has a single png attached and not my animation.

Draw:
myPlayer = new Player(TextureLibrary.GetTexture("player"), myPlayerPos, 200, new Vector2(.3f, .3f), 0, Color.White, 1000, 1);

Body:
Based on your code you have given. I think you just need to change some things.

First, use the SpriteSheetPlayerAnim as the texture of your player directly instead of using player texture.

Then move the code of Update and Draw of player's animation to Update and Draw of Player class.

They will be like this:

public class Player
{
    //Default constructor
    public Player()
    {
        //default values for your player//for example only
        //this.hp = 100;
        //this.mp = 20;
    }

    //Constructor
    public Player(GameTime myelapsedGameTime, Texture2D texPlayer, Vector2 playerPosition, int something, Vector2 vector2ForSomething, int intFST, Color playerColor, ...)
    {
        //initialise player's attributes

    }

    public override Update(GameTime gameTime)
    {
        if (myElapsed >= myDelay)
        {
            if (myFrames >= 3)
            {
                myFrames = 0;
            }
            else
            {
                myFrames++;
            }
            myElapsed = 0;
        }
    }

    public override Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(myPlayerAnim, myDestRect , mySourceRect,
            Color.White);//for example
    }
}

Then in your Game1 class:

public class Game1 : Game
{
    Player player;
    GameTime myElapsed;

    public Game1()
    {
        //
    }

    protected override void LoadContent()
    {
        //Load your animated sprite here
        myPlayerAnim = Content.Load<Texture2D>("SpriteSheetPlayerAnim");

        player = new Player(myElapsed, myPlayerAnim, ...);//constructor with attributes here or whatever you want
    }

    protected override void Update(GameTime gameTime)
    {
        myElapsed += (float)aGameTime.ElapsedGameTime.TotalMilliseconds;
        player.Update(gameTime);
    }

    protected override void Draw(SpriteBatch spriteBatch)
    {
        player.Draw(spriteBatch);
    }
}

Hope this helps!


答:
You were not passing the callback properly. By passing the callback to .setState() the second function will run once the first function finish setting state.

```<code>componentDidMount = async () => {
  const communities = await API.getUserCommunityInfo(userId);
  console.log(communities);
  this.setState(
    {
      userCommunities: communities,
      communityMemberId: communities[0].member.id,
      communityId: communities[0].community.id
    },
    () => {
      console.log(this.state);
      this.getGroups()
    }
  );
};
</code>```

getGroups function

```<code>getGroups = async () => {
  const groups = await API.getGroups(this.state.communityMemberId)
  this.setState({userGroups: groups ,showLoader: false})
}
</code>```

Body:
You were not passing the callback properly. By passing the callback to .setState() the second function will run once the first function finish setting state.

componentDidMount = async () => {
  const communities = await API.getUserCommunityInfo(userId);
  console.log(communities);
  this.setState(
    {
      userCommunities: communities,
      communityMemberId: communities[0].member.id,
      communityId: communities[0].community.id
    },
    () => {
      console.log(this.state);
      this.getGroups()
    }
  );
};

getGroups function

getGroups = async () => {
  const groups = await API.getGroups(this.state.communityMemberId)
  this.setState({userGroups: groups ,showLoader: false})
}


问:
How to merge two arrays (song&title) into one multidimensional array?
I have two arrays:

```<code>Array
(
 [0] => Black
 [1] => Five Hours
 [2] => Bvulgari
 [3] => Imaginary
)

Array
(
 [0] => Pearl Jam
 [1] => Deorro
 [2] => Daddy's Groove
 [3] => Brennan Heart
)
</code>```

I want to be able to achieve the following:
I want to have the song title and the Artist into one 'dimension' of the array,
This is how I want it to be:

```<code>Array
(
     [0] => Array
            (
              [0] => Black
              [1] => Pearl Jam
            )
     [1] => Array
            (
              [0] => Five Hours
              [1] => Deorro
            )
     [2] => Array
            (
              [0] => Bvulgari
              [1] => Daddy's Groove

            )
     [3] => Array
            (
              [0] => Imaginary
              [1] => Brennan Heart
            )

)
</code>```

The two arrays that are the input can change depending on the requestor's input.

答:
You can use a simple foreach loop:

```<code>$songs_artists = array();
foreach ($songs as $key => $title) {
    $songs_artists[] = array($title, $artists[$key]);
}
</code>```

Output is as you desire. Demo on 3v4l.org

Body:
I have two arrays:

Array
(
 [0] => Black
 [1] => Five Hours
 [2] => Bvulgari
 [3] => Imaginary
)

Array
(
 [0] => Pearl Jam
 [1] => Deorro
 [2] => Daddy's Groove
 [3] => Brennan Heart
)

I want to be able to achieve the following:
I want to have the song title and the Artist into one 'dimension' of the array,
This is how I want it to be:

Array
(
     [0] => Array
            (
              [0] => Black
              [1] => Pearl Jam
            )
     [1] => Array
            (
              [0] => Five Hours
              [1] => Deorro
            )
     [2] => Array
            (
              [0] => Bvulgari
              [1] => Daddy's Groove

            )
     [3] => Array
            (
              [0] => Imaginary
              [1] => Brennan Heart
            )

)

The two arrays that are the input can change depending on the requestor's input.

Body:
You can use a simple foreach loop:

$songs_artists = array();
foreach ($songs as $key => $title) {
    $songs_artists[] = array($title, $artists[$key]);
}

Output is as you desire. Demo on 3v4l.org


问:
Linked lists in C, how to fix expected identifier error?
I am new to C and I can't get this thing to compile properly, can you help me?

```<code>struct tagNode
{
    int v, f;

    struct tagNode *next;

    struct tagNode( int _v )
    {
        v = _v;
        next = NULL;
    }
};
</code>```

expected identifier or ‘(’ before ‘int’:
     struct tagNode( int _v )

答:
expected identifier or ‘(’ before ‘int’: struct tagNode( int _v )

this is because of the unexpected struct when you compile in C++

A valid version of your code in C++ can be:

```<code>struct tagNode
{
    int v, f;

    tagNode *next;

    tagNode (int _v)
    {
        v = _v;
        next = NULL;
    }
};
</code>```

but

what about f ?

the constructor can also be tagNode(int _v) : v(_v), next(NULL) {}

and you have a pointer so I recommend you to look at the rule of three

There is no constructor/methods in C so the equivalent of your code in C can be :

```<code>#include <stdlib.h>

struct tagNode
{
  int v, f;
  struct tagNode * next;
};

struct tagNode * alloc(int _v)
{
  struct tagNode * r = malloc(sizeof(struct tagNode));

  r->v = _v;
  r->next = NULL;
  return r;
}
</code>```

Body:
I am new to C and I can't get this thing to compile properly, can you help me?

struct tagNode
{
    int v, f;

    struct tagNode *next;

    struct tagNode( int _v )
    {
        v = _v;
        next = NULL;
    }
};

expected identifier or ‘(’ before ‘int’:
     struct tagNode( int _v )

Body:
expected identifier or ‘(’ before ‘int’: struct tagNode( int _v )

this is because of the unexpected struct when you compile in C++

A valid version of your code in C++ can be:

struct tagNode
{
    int v, f;

    tagNode *next;

    tagNode (int _v)
    {
        v = _v;
        next = NULL;
    }
};

but

what about f ?

the constructor can also be tagNode(int _v) : v(_v), next(NULL) {}

and you have a pointer so I recommend you to look at the rule of three

There is no constructor/methods in C so the equivalent of your code in C can be :

#include <stdlib.h>

struct tagNode
{
  int v, f;
  struct tagNode * next;
};

struct tagNode * alloc(int _v)
{
  struct tagNode * r = malloc(sizeof(struct tagNode));

  r->v = _v;
  r->next = NULL;
  return r;
}


问:
Modify keys in Spray JSON
Suppose I have a JSON object as follows:

```<code>{
  "CATEGORY": "reference",
  "AUTHOR": "Nigel Rees",
  "TITLE": "Sayings of the Century",
  "PRICE": 8.95
}
</code>```

This flows in the system as a JsObject. Using Spray, how would I lowercase these fields?

答:
This code:

```<code>import spray.json._

val str =
    """{"CATEGORY": "reference",
        "AUTHOR":  "Nigel Rees",
        "TITLE": "Sayings of the Century",
        "PRICE": 8.95}"""

  def main(args: Array[String]) : Unit =
    println(JsObject(str.parseJson.asJsObject.fields.map(el => el._1.asInstanceOf[String].toLowerCase -> el._2 )))
</code>```

gives:

```<code>{"author":"Nigel Rees","category":"reference","price":8.95,"title":"Sayings of the Century"}
</code>```

With the following dependence in sbt:

```<code>"com.typesafe.akka" %% "akka-http-spray-json" % "10.1.8"
</code>```

Title: Modify keys in Spray JSON

Body:
Suppose I have a JSON object as follows:

{
  "CATEGORY": "reference",
  "AUTHOR": "Nigel Rees",
  "TITLE": "Sayings of the Century",
  "PRICE": 8.95
}

This flows in the system as a JsObject. Using Spray, how would I lowercase these fields?

Body:
This code:

import spray.json._

val str =
    """{"CATEGORY": "reference",
        "AUTHOR":  "Nigel Rees",
        "TITLE": "Sayings of the Century",
        "PRICE": 8.95}"""

  def main(args: Array[String]) : Unit =
    println(JsObject(str.parseJson.asJsObject.fields.map(el => el._1.asInstanceOf[String].toLowerCase -> el._2 )))

gives:

{"author":"Nigel Rees","category":"reference","price":8.95,"title":"Sayings of the Century"}

With the following dependence in sbt:

"com.typesafe.akka" %% "akka-http-spray-json" % "10.1.8"


问:
Stop return back to first function
I'd like to stop returning to the first function. Look at my example for better understanding:</p>

```<code>function function1() {
    function2();
    console.log('back after called function'); // shoudn't log if condition is true
}

function function2() {
    if (condition === true) { // if condition is true, stop right here (no callback to function1)
        return false;
    } else {
        // callback is allowed
    }
}
</code>```

答:
Use a ternary operator.

```<code>function2() ? false : console.log('back after called function');
</code>```

You can add more lines in as well - use an IIFE.

```<code>function2() ? false : (() => {
    console.log('back after called function');
    //More code
})();
</code>```

Title: Stop return back to first function

Body:
I'd like to stop returning to the first function. Look at my example for better understanding:

function function1() {
    function2();
    console.log('back after called function'); // shoudn't log if condition is true
}

function function2() {
    if (condition === true) { // if condition is true, stop right here (no callback to function1)
        return false;
    } else {
        // callback is allowed
    }
}

Body:
Use a ternary operator.

function2() ? false : console.log('back after called function');

You can add more lines in as well - use an IIFE.

function2() ? false : (() => {
    console.log('back after called function');
    //More code
})();


问:
@CrossOrigin(origins = "*") is not working in firefox
In my controller class I've specified @CrossOrigin(origins = "*") and I'm trying to connect my angular app but it's not working. I know it's because of Angular is running on 4200 port and Java app is running on 8080 port but is there any way to do it? Without deploying war?

```<code>@CrossOrigin(origins = "*")
@RestController
public class UserController {
//
}
</code>```

答:
If you are using Spring boot

CORS support is disabled by default and is only enabled once the
  management.endpoints.web.cors.allowed-origins property has been set.

Also according to CORS support in Spring Framework

If you are using Spring Security, make sure to enable CORS at Spring
  Security level as well to allow it to leverage the configuration
  defined at Spring MVC level.

One more problem could be CORSMIssingAllowCredentials

If the request is being issued using XMLHttpRequest, make sure you're
  not setting withCredentials to true.

Firefox Does not support CORS for resources which redirect

Body:
In my controller class I've specified @CrossOrigin(origins = "*") and I'm trying to connect my angular app but it's not working. I know it's because of Angular is running on 4200 port and Java app is running on 8080 port but is there any way to do it? Without deploying war?

@CrossOrigin(origins = "*")
@RestController
public class UserController {
//
}


答:
There's a bug in this line:

```<code>flight_list[1]->price = 70;
</code>```

Both [] and -> dereference pointers. a[b] is equivalent to *(a+b) and a->b is equivalent to (*a).b. Your line therefore means:

```<code>(**(flight_list + 1)).price = 70;
</code>```

However, flight_list (in load_flights) is a pointer to the flight_list variable in main! In the context of main, you're computing &flight_list + 1, which is an invalid pointer: You're getting the contents of memory that happens to be next to a local variable.

The correct code would be:

```<code>(*(*flight_list + 1)).price = 70;
</code>```

*flight_list is the pointer returned by realloc. Here we can step one element ahead in the dynamic array.

We can also write this as:

```<code>(*flight_list)[1].price = 70;
</code>```

Title: realloc not allocating memory for next struct

Body:
There's a bug in this line:

flight_list[1]->price = 70;

Both [] and -> dereference pointers. a[b] is equivalent to *(a+b) and a->b is equivalent to (*a).b. Your line therefore means:

(**(flight_list + 1)).price = 70;

However, flight_list (in load_flights) is a pointer to the flight_list variable in main! In the context of main, you're computing &flight_list + 1, which is an invalid pointer: You're getting the contents of memory that happens to be next to a local variable.

The correct code would be:

(*(*flight_list + 1)).price = 70;

*flight_list is the pointer returned by realloc. Here we can step one element ahead in the dynamic array.

We can also write this as:

(*flight_list)[1].price = 70;


问:
Can i use C++ function pointers like a C#'s Action?
In C ++, I first encountered function pointers.

I tried to use this to make it similar to Action and Delegate in C #.

However, when declaring a function pointer, it is necessary to specify the type of the class in which the function exists.

ex) void (A :: * F) ();

Can I use a function pointer that can store a member function of any class?

In general, function pointers are used as shown in the code below.

```<code>class A {
public:
    void AF() { cout << "A::F" << endl; }
};

class B {
public:
    void(A::*BF)();
};

int main()
{
    A a;
    B b;

    b.BF = &A::AF;
    (a.*b.BF)();

    return 0;
}
</code>```

I want to use it like the code below.

is this possible?

Or is there something else to replace the function pointer?

```<code>class A {
public:
    void AF() { cout << "A::F" << endl; }
};

class B {
public:
    void(* BF)();
};

int main()
{
    A a;
    B b;

    b.BF = a.AF;

    return 0;
}
</code>```

I solved the question through the answer.

Thanks!

```<code>#include <functional>
#include <iostream>

class A {
public:
    void AF() { std::cout << "A::F" << std::endl; }
};

class C {
public:
    void CF() { std::cout << "C::F" << std::endl; }
};

class B {
public:
    B(){}
    std::function<void()> BF;
};

int main() {
    A a;
    C c;
    B b;
    b.BF = std::bind(&A::AF, &a);
    b.BF();
    b.BF = std::bind(&C::CF, &c);
    b.BF();

    int i;
    std::cin >> i;
    return 0;
}
</code>```

答:
What you want to do is probably something like this. You can use std::function to hold a pointer to a member function bound to a specific instance.

```<code>#include <functional>
#include <iostream>

class A {
public:
    void AF() { std::cout << "A::F" << std::endl; }
};

class B {
public:
    B(const std::function<void()>& bf) : BF(bf) {}
    std::function<void()> BF;
};

int main() {
    A a;
    B b1(std::bind(&A::AF, &a)); // using std::bind
    B b2([&a] { a.AF(); });      // using a lambda

    b1.BF();
    b2.BF();

    return 0;
}
</code>```

Body:
In C ++, I first encountered function pointers.

I tried to use this to make it similar to Action and Delegate in C #.

However, when declaring a function pointer, it is necessary to specify the type of the class in which the function exists.

ex) void (A :: * F) ();

Can I use a function pointer that can store a member function of any class?

In general, function pointers are used as shown in the code below.

class A {
public:
    void AF() { cout << "A::F" << endl; }
};

class B {
public:
    void(A::*BF)();
};

int main()
{
    A a;
    B b;

    b.BF = &A::AF;
    (a.*b.BF)();

    return 0;
}

I want to use it like the code below.

is this possible?

Or is there something else to replace the function pointer?

class A {
public:
    void AF() { cout << "A::F" << endl; }
};

class B {
public:
    void(* BF)();
};

int main()
{
    A a;
    B b;

    b.BF = a.AF;

    return 0;
}

I solved the question through the answer.

Thanks!

#include <functional>
#include <iostream>

class A {
public:
    void AF() { std::cout << "A::F" << std::endl; }
};

class C {
public:
    void CF() { std::cout << "C::F" << std::endl; }
};

class B {
public:
    B(){}
    std::function<void()> BF;
};

int main() {
    A a;
    C c;
    B b;
    b.BF = std::bind(&A::AF, &a);
    b.BF();
    b.BF = std::bind(&C::CF, &c);
    b.BF();

    int i;
    std::cin >> i;
    return 0;
}

Body:
What you want to do is probably something like this. You can use std::function to hold a pointer to a member function bound to a specific instance.

#include <functional>
#include <iostream>

class A {
public:
    void AF() { std::cout << "A::F" << std::endl; }
};

class B {
public:
    B(const std::function<void()>& bf) : BF(bf) {}
    std::function<void()> BF;
};

int main() {
    A a;
    B b1(std::bind(&A::AF, &a)); // using std::bind
    B b2([&a] { a.AF(); });      // using a lambda

    b1.BF();
    b2.BF();

    return 0;
}