问:
Remove from slice inplace in Golang
I have the following test that is printing the original input slice (after the filtering) without the element that has been removed, but with an extra element at the end making the input slice of the same length, even if after the filtering it should be shorter.

I've gone through this doc https://github.com/golang/go/wiki/SliceTricks#delete
However I think I am missing some gotchas about Go, because it seems I am using slices with the wrong approach.

how can I avoid to have an "output slice"? (which is printed in the correct way, containing the right elements, having the expected length and capacity)

why my attempt at "removing inplace" leads to having the "input slice" with the same length as it had before the filtering process?

why the "input slice" has the same length as before I was applying the filtering process? How can I make the remove operation to change the length of the "input slice"?

This is the code:

```<code>package foo

import (
    "fmt"
    "log"
    "math/rand"
    "testing"
)

type FooItem struct {
    Id       int
    Category string
    Value    float64
}

const minRand = 0
const maxRand = 10

const maxSliceLen = 3

var inFooSlice []FooItem

func init() {
    for i := 1; i <= maxSliceLen; i++ {
        inFooSlice = append(inFooSlice, FooItem{
            Id:       i,
            Category: "FooCat",
            Value:    minRand + rand.Float64()*(maxRand-minRand),
        })
    }
}

// this is the function I am testing
func FindAndRemoveFromFooSlice(iFilter int, inSl []FooItem) (*FooItem, []FooItem) {

    inLen := len(inSl)
    outSl := make([]FooItem, inLen)

    for idx, elem := range inSl {
        if elem.Id == iFilter {
            log.Printf("Loop ID %v", idx)

            // check these docs: https://github.com/golang/go/wiki/SliceTricks#delete
            outSl = inSl[:idx+copy(inSl[idx:], inSl[idx+1:inLen])]
            outSl = outSl[:inLen-1]

            return &elem, outSl
        }
    }
    return nil, nil
}

func TestFoo(t *testing.T) {
    fmt.Printf("\nOriginal (PRE) slice\n")
    fmt.Println(inFooSlice)
    fmt.Println(len(inFooSlice))
    fmt.Println(cap(inFooSlice))

    idFilter := 1

    fePtr, outFooSlice := FindAndRemoveFromFooSlice(idFilter, inFooSlice)

    fmt.Printf("\nOriginal (POST) slice\n")
    fmt.Println(inFooSlice)
    fmt.Println(len(inFooSlice))
    fmt.Println(cap(inFooSlice))

    fmt.Printf("\nFiltered element\n")
    fmt.Println(*fePtr)

    fmt.Printf("\nOutput slice\n")
    fmt.Println(outFooSlice)
    fmt.Println(len(outFooSlice))
    fmt.Println(cap(outFooSlice))
}
</code>```

This is the output of the test execution:

```<code>$ go test -v -run TestFoo
=== RUN   TestFoo

Original (PRE) slice
[{1 FooCat 6.046602879796196} {2 FooCat 9.405090880450125} {3 FooCat 6.645600532184904}]
3
4
2019/05/31 12:53:30 Loop ID 0

Original (POST) slice
[{2 FooCat 9.405090880450125} {3 FooCat 6.645600532184904} {3 FooCat 6.645600532184904}]
3
4

Filtered element
{1 FooCat 6.046602879796196}

Output slice
[{2 FooCat 9.405090880450125} {3 FooCat 6.645600532184904}]
2
4
--- PASS: TestFoo (0.00s)
PASS
ok      git.openenergi.net/scm/flex/service/common  0.008s
</code>```

Update on the "input slice as pointer"

OK, so assuming I would like to deal with the original input slice, i.e. no copy or output slice.

Why the following code throws a runtime panic in the commented line of code? (pointedInSl[inLen-1] = FooItem{})

Why the printed slice (after applying the function) contains 2 identical itmes at the end of it? How con I remove the last redundant element?

Why the length of the slice after applying the function is still the same as the one of the slice before applying the function?

How can I make the original slice shrink of 1 (i.e. being of output length = original length - 1)?

This is the code:

```<code>func FindAndRemoveFromFooSliceInPlace(iFilter int, inSl *[]FooItem) *FooItem {
    pointedInSl := *inSl
    inLen := len(pointedInSl)
    for idx, elem := range pointedInSl {
        if elem.Id == iFilter {
            log.Printf("Loop ID %v", idx)

            // check these docs: https://github.com/golang/go/wiki/SliceTricks#delete
            pointedInSl = append(pointedInSl[:idx], pointedInSl[idx+1:inLen]...)
            // pointedInSl[inLen-1] = FooItem{} // why this throws a runtime "panic: runtime error: index out of range" ???
            pointedInSl = pointedInSl[:inLen-1]

            return &elem
        }
    }
    return nil
}

func TestFooInPlace(t *testing.T) {
    fmt.Printf("\nOriginal (PRE) slice\n")
    fmt.Println(inFooSlice)
    fmt.Println(len(inFooSlice))
    fmt.Println(cap(inFooSlice))

    idFilter := 1

    fePtr := FindAndRemoveFromFooSliceInPlace(idFilter, &inFooSlice)

    fmt.Printf("\nOriginal (POST) slice\n")
    fmt.Println(inFooSlice)
    fmt.Println(len(inFooSlice))
    fmt.Println(cap(inFooSlice))

    fmt.Printf("\nFiltered element\n")
    fmt.Println(*fePtr)
}
</code>```

This is the weird output:

```<code>$ go test -v -run TestFooInPlace
=== RUN   TestFooInPlace

Original (PRE) slice
[{1 FooCat 6.046602879796196} {2 FooCat 9.405090880450125} {3 FooCat 6.645600532184904}]
3
4
2019/05/31 16:32:38 Loop ID 0

Original (POST) slice
[{2 FooCat 9.405090880450125} {3 FooCat 6.645600532184904} {3 FooCat 6.645600532184904}]
3
4

Filtered element
{1 FooCat 6.046602879796196}
--- PASS: TestFooInPlace (0.00s)
PASS
ok      git.openenergi.net/scm/flex/service/common  0.007s
</code>```

答:
When you have a variable of int type, and you want to write a function that increments its value, how do you do it? You either pass a pointer to the variable, or you return the incremented value which you have to assign to the original variable.

For example (try it on the Go Playground):

```<code>func inc(i int) int { i++; return i }

var i int = 2
inc(i)
fmt.Println(i) // This will be 2
</code>```

In the above code you pass i to inc() which increments it and returns its value. The original i of course will not change, i inside inc() is just a copy, independent form the original i. For the original to change, you would have to assing the return value:

```<code>i = inc(i)
</code>```

Or use pointers in the first place (try it on the Go Playground):

```<code>func inc(i *int) { *i++ }

var i int = 2
inc(&i)
fmt.Println(i) // This will be 3
</code>```

The same thing goes with slices. If you want / have to modify the slice header (which is a data pointer, length and capacity, see reflect.SliceHeader), you either have to pass a pointer to that slice (not very common), or you have to return the modified, new slice header which you have to assign at the caller. This is the solution used more often, this is the approach the builtin append() follows too.

When you slice a slice, (e.g. someslice[min:max]), the new slice will share the backing array with the original one. Which means if you modify the elements of the new slice, the original will also observe those changes. So if you remove an element from the new slice and you copy the elements to the place of the removed element, the last element of the original slice will still be there, which is "covered" by the original slice. Usual practice is to zero the last element so the garbage collector can reclaim its memory should it be a pointer type (or "similar" like a slice, map or channel). For details, see Memory leak in golang slice and Does go garbage collect parts of slices?

To answer you questions directly:

how can I avoid to have an "output slice"? (which is printed in the correct way, containing the right elements, having the expected length and capacity)

As stated in this answer: you would have to pass a pointer to your slice, and modify the pointed value in FindAndRemoveFromFooSlice(), and so you don't have to return the new slice.

why my attempt at "removing inplace" leads to having the "input slice" with the same length as it had before the filtering process?

You never modified the original slice, you passed it so a copy is made, and inside FindAndRemoveFromFooSlice() you can only modify the copy (but you didn't even modify the copy). You return a new slice, but you didn't assign it, so the original slice (header) is intact.

why the "input slice" has the same length as before I was applying the filtering process? How can I make the remove operation to change the length of the "input slice"?

This is answered by the previous 2 questions.

See related questions:

Are golang slices pass by value?

slice vs map to be used in parameter

Title: Remove from slice inplace in Golang

Body:
I have the following test that is printing the original input slice (after the filtering) without the element that has been removed, but with an extra element at the end making the input slice of the same length, even if after the filtering it should be shorter.

I've gone through this doc https://github.com/golang/go/wiki/SliceTricks#delete
However I think I am missing some gotchas about Go, because it seems I am using slices with the wrong approach.

how can I avoid to have an "output slice"? (which is printed in the correct way, containing the right elements, having the expected length and capacity)

why my attempt at "removing inplace" leads to having the "input slice" with the same length as it had before the filtering process?

why the "input slice" has the same length as before I was applying the filtering process? How can I make the remove operation to change the length of the "input slice"?

This is the code:

package foo

import (
    "fmt"
    "log"
    "math/rand"
    "testing"
)

type FooItem struct {
    Id       int
    Category string
    Value    float64
}

const minRand = 0
const maxRand = 10

const maxSliceLen = 3

var inFooSlice []FooItem

func init() {
    for i := 1; i <= maxSliceLen; i++ {
        inFooSlice = append(inFooSlice, FooItem{
            Id:       i,
            Category: "FooCat",
            Value:    minRand + rand.Float64()*(maxRand-minRand),
        })
    }
}

// this is the function I am testing
func FindAndRemoveFromFooSlice(iFilter int, inSl []FooItem) (*FooItem, []FooItem) {

    inLen := len(inSl)
    outSl := make([]FooItem, inLen)

    for idx, elem := range inSl {
        if elem.Id == iFilter {
            log.Printf("Loop ID %v", idx)

            // check these docs: https://github.com/golang/go/wiki/SliceTricks#delete
            outSl = inSl[:idx+copy(inSl[idx:], inSl[idx+1:inLen])]
            outSl = outSl[:inLen-1]

            return &elem, outSl
        }
    }
    return nil, nil
}

func TestFoo(t *testing.T) {
    fmt.Printf("\nOriginal (PRE) slice\n")
    fmt.Println(inFooSlice)
    fmt.Println(len(inFooSlice))
    fmt.Println(cap(inFooSlice))

    idFilter := 1

    fePtr, outFooSlice := FindAndRemoveFromFooSlice(idFilter, inFooSlice)

    fmt.Printf("\nOriginal (POST) slice\n")
    fmt.Println(inFooSlice)
    fmt.Println(len(inFooSlice))
    fmt.Println(cap(inFooSlice))

    fmt.Printf("\nFiltered element\n")
    fmt.Println(*fePtr)

    fmt.Printf("\nOutput slice\n")
    fmt.Println(outFooSlice)
    fmt.Println(len(outFooSlice))
    fmt.Println(cap(outFooSlice))
}

This is the output of the test execution:

$ go test -v -run TestFoo
=== RUN   TestFoo

Original (PRE) slice
[{1 FooCat 6.046602879796196} {2 FooCat 9.405090880450125} {3 FooCat 6.645600532184904}]
3
4
2019/05/31 12:53:30 Loop ID 0

Original (POST) slice
[{2 FooCat 9.405090880450125} {3 FooCat 6.645600532184904} {3 FooCat 6.645600532184904}]
3
4

Filtered element
{1 FooCat 6.046602879796196}

Output slice
[{2 FooCat 9.405090880450125} {3 FooCat 6.645600532184904}]
2
4
--- PASS: TestFoo (0.00s)
PASS
ok      git.openenergi.net/scm/flex/service/common  0.008s

Update on the "input slice as pointer"

OK, so assuming I would like to deal with the original input slice, i.e. no copy or output slice.

Why the following code throws a runtime panic in the commented line of code? (pointedInSl[inLen-1] = FooItem{})

Why the printed slice (after applying the function) contains 2 identical itmes at the end of it? How con I remove the last redundant element?

Why the length of the slice after applying the function is still the same as the one of the slice before applying the function?

How can I make the original slice shrink of 1 (i.e. being of output length = original length - 1)?

This is the code:

func FindAndRemoveFromFooSliceInPlace(iFilter int, inSl *[]FooItem) *FooItem {
    pointedInSl := *inSl
    inLen := len(pointedInSl)
    for idx, elem := range pointedInSl {
        if elem.Id == iFilter {
            log.Printf("Loop ID %v", idx)

            // check these docs: https://github.com/golang/go/wiki/SliceTricks#delete
            pointedInSl = append(pointedInSl[:idx], pointedInSl[idx+1:inLen]...)
            // pointedInSl[inLen-1] = FooItem{} // why this throws a runtime "panic: runtime error: index out of range" ???
            pointedInSl = pointedInSl[:inLen-1]

            return &elem
        }
    }
    return nil
}

func TestFooInPlace(t *testing.T) {
    fmt.Printf("\nOriginal (PRE) slice\n")
    fmt.Println(inFooSlice)
    fmt.Println(len(inFooSlice))
    fmt.Println(cap(inFooSlice))

    idFilter := 1

    fePtr := FindAndRemoveFromFooSliceInPlace(idFilter, &inFooSlice)

    fmt.Printf("\nOriginal (POST) slice\n")
    fmt.Println(inFooSlice)
    fmt.Println(len(inFooSlice))
    fmt.Println(cap(inFooSlice))

    fmt.Printf("\nFiltered element\n")
    fmt.Println(*fePtr)
}

This is the weird output:

$ go test -v -run TestFooInPlace
=== RUN   TestFooInPlace

Original (PRE) slice
[{1 FooCat 6.046602879796196} {2 FooCat 9.405090880450125} {3 FooCat 6.645600532184904}]
3
4
2019/05/31 16:32:38 Loop ID 0

Original (POST) slice
[{2 FooCat 9.405090880450125} {3 FooCat 6.645600532184904} {3 FooCat 6.645600532184904}]
3
4

Filtered element
{1 FooCat 6.046602879796196}
--- PASS: TestFooInPlace (0.00s)
PASS
ok      git.openenergi.net/scm/flex/service/common  0.007s

Body:
When you have a variable of int type, and you want to write a function that increments its value, how do you do it? You either pass a pointer to the variable, or you return the incremented value which you have to assign to the original variable.

For example (try it on the Go Playground):

func inc(i int) int { i++; return i }

var i int = 2
inc(i)
fmt.Println(i) // This will be 2

In the above code you pass i to inc() which increments it and returns its value. The original i of course will not change, i inside inc() is just a copy, independent form the original i. For the original to change, you would have to assing the return value:

i = inc(i)

Or use pointers in the first place (try it on the Go Playground):

func inc(i *int) { *i++ }

var i int = 2
inc(&i)
fmt.Println(i) // This will be 3

The same thing goes with slices. If you want / have to modify the slice header (which is a data pointer, length and capacity, see reflect.SliceHeader), you either have to pass a pointer to that slice (not very common), or you have to return the modified, new slice header which you have to assign at the caller. This is the solution used more often, this is the approach the builtin append() follows too.

When you slice a slice, (e.g. someslice[min:max]), the new slice will share the backing array with the original one. Which means if you modify the elements of the new slice, the original will also observe those changes. So if you remove an element from the new slice and you copy the elements to the place of the removed element, the last element of the original slice will still be there, which is "covered" by the original slice. Usual practice is to zero the last element so the garbage collector can reclaim its memory should it be a pointer type (or "similar" like a slice, map or channel). For details, see Memory leak in golang slice and Does go garbage collect parts of slices?

To answer you questions directly:

how can I avoid to have an "output slice"? (which is printed in the correct way, containing the right elements, having the expected length and capacity)

As stated in this answer: you would have to pass a pointer to your slice, and modify the pointed value in FindAndRemoveFromFooSlice(), and so you don't have to return the new slice.

why my attempt at "removing inplace" leads to having the "input slice" with the same length as it had before the filtering process?

You never modified the original slice, you passed it so a copy is made, and inside FindAndRemoveFromFooSlice() you can only modify the copy (but you didn't even modify the copy). You return a new slice, but you didn't assign it, so the original slice (header) is intact.

why the "input slice" has the same length as before I was applying the filtering process? How can I make the remove operation to change the length of the "input slice"?

This is answered by the previous 2 questions.

See related questions:

Are golang slices pass by value?

slice vs map to be used in parameter


来源: stackexchange

问:
Cannot find either column "databasename" or the user-defined function or aggregate "databasename.dbo.GetAliasesByACC", or the name is ambiguous
```<code>Create FUNCTION [dbo].[GetAliasesByACC]
(
    @AccID int
)
RETURNS varchar(max)
AS
BEGIN
    declare @output varchar(max)
    select @output = COALESCE(@output + ', ', '') + Docnum
    from OPOR
    where TransID = @AccID
    return @output
END
</code>```

am Creating this function and call to UDF Field in SAP B1 AR invoice,

```<code>Declare @Var as nvarchar(max)
set @Var= [databasename].[dbo].GetAliasesByACC(value)
select @Var
</code>```

Like this i have to call UDF field into this FMS query but showing some error  please check it.

Error: 1). [Microsoft][SQL Server Native Client 11.0][SQL Server]Cannot find either column "databasename"
  or the user-defined function or aggregate "databasename.dbo.GetAliasesByACC", or the name is ambiguous.

2). [Microsoft][SQL Server Native Client 11.0][SQL

Please solve this anone

答:
databasename it must be your database name.

Calling function in sql is like...

```<code> Declare @Var as nvarchar(max)
 set @Var= (Select  [databasename].[dbo].GetAliasesByACC(value) as OutVal)
 select @Var
</code>```

ContentLicense: CC BY-SA 4.0

Body:
Create FUNCTION [dbo].[GetAliasesByACC]
(
    @AccID int
)
RETURNS varchar(max)
AS
BEGIN
    declare @output varchar(max)
    select @output = COALESCE(@output + ', ', '') + Docnum
    from OPOR
    where TransID = @AccID
    return @output
END

am Creating this function and call to UDF Field in SAP B1 AR invoice,

Declare @Var as nvarchar(max)
set @Var= [databasename].[dbo].GetAliasesByACC(value)
select @Var

Like this i have to call UDF field into this FMS query but showing some error  please check it.

Error: 1). [Microsoft][SQL Server Native Client 11.0][SQL Server]Cannot find either column "databasename"
  or the user-defined function or aggregate "databasename.dbo.GetAliasesByACC", or the name is ambiguous.

2). [Microsoft][SQL Server Native Client 11.0][SQL

Please solve this anone

Body:
databasename it must be your database name.

Calling function in sql is like...

 Declare @Var as nvarchar(max)
 set @Var= (Select  [databasename].[dbo].GetAliasesByACC(value) as OutVal)
 select @Var


问:
Fixed position for sidebar and mainpanel in RShiny
I want to have a fixed-width sidebar in my RShiny application which stays in place when resizing the window.

I have managed getting a fixed-width sidebar, but there is still white spacing between the sidebar and the main panel. It seems like there should be a straight-forward solution to this, but my searches has this far been futile.

Here is a minimal example based on the 'Old Faithful Geyser Data' template. I have added tags which keeps the side panel to a fixed width.

library(shiny)

ui <- fluidPage(

   titlePanel("Old Faithful Geyser Data"),
   sidebarLayout(
      sidebarPanel(
          tags$head(
              tags$style(type="text/css", "select { max-width: 240px; }"),
              tags$style(type="text/css", ".span4 { max-width: 290px; }"),
              tags$style(type="text/css", ".well { max-width: 280px; }")
          ),
         sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)
      ),
      mainPanel(
         plotOutput("distPlot")
      )
   )
)

server <- function(input, output) {
   output$distPlot <- renderPlot({
      x    <- faithful[, 2]
      bins <- seq(min(x), max(x), length.out = input$bins + 1)
      hist(x, breaks = bins, col = 'darkgray', border = 'white')
   })
}

shinyApp(ui = ui, server = server)
```

The normal output looks good.

When dragging the window the sidebar get very wide, taking valuable screen estate from the main panel.

When fixing the width of the sidebar panel it stays in shape when expanding the window, but the main panel is not able to utilize the full area. The desired reaction is that the sidebar panel stays in size and the main panel can utilize all the available space.

Anyone having any ideas for how to approach this? Thanks!

答:
Is it OK like this?:</p>

```<code>library(shiny)

ui <- fluidPage(
  tags$head(
    tags$style(type="text/css", "select { max-width: 240px; }"),
    tags$style(type="text/css", ".span4 { max-width: 290px; }"),
    tags$style(type="text/css", ".well { max-width: 280px; }")
  ),

  titlePanel("Old Faithful Geyser Data"),
  div(
    style = "display:flex; align-items:flex-start",
    wellPanel( # sidebar
      sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30),
      textInput("text", "Enter text:")
    ),
    div( # main panel
      style = "flex-grow:1; resize:horizontal; overflow: hidden",
      plotOutput("distPlot")
    )
  )
)

server <- function(input, output) {
  output$distPlot <- renderPlot({
    x    <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
}

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

Body:
I want to have a fixed-width sidebar in my RShiny application which stays in place when resizing the window.

I have managed getting a fixed-width sidebar, but there is still white spacing between the sidebar and the main panel. It seems like there should be a straight-forward solution to this, but my searches has this far been futile.

Here is a minimal example based on the 'Old Faithful Geyser Data' template. I have added tags which keeps the side panel to a fixed width.

library(shiny)

ui <- fluidPage(

   titlePanel("Old Faithful Geyser Data"),
   sidebarLayout(
      sidebarPanel(
          tags$head(
              tags$style(type="text/css", "select { max-width: 240px; }"),
              tags$style(type="text/css", ".span4 { max-width: 290px; }"),
              tags$style(type="text/css", ".well { max-width: 280px; }")
          ),
         sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)
      ),
      mainPanel(
         plotOutput("distPlot")
      )
   )
)

server <- function(input, output) {
   output$distPlot <- renderPlot({
      x    <- faithful[, 2]
      bins <- seq(min(x), max(x), length.out = input$bins + 1)
      hist(x, breaks = bins, col = 'darkgray', border = 'white')
   })
}

shinyApp(ui = ui, server = server)

The normal output looks good.

When dragging the window the sidebar get very wide, taking valuable screen estate from the main panel.

When fixing the width of the sidebar panel it stays in shape when expanding the window, but the main panel is not able to utilize the full area. The desired reaction is that the sidebar panel stays in size and the main panel can utilize all the available space.

Anyone having any ideas for how to approach this? Thanks!

Body:
Is it OK like this?:

library(shiny)

ui <- fluidPage(
  tags$head(
    tags$style(type="text/css", "select { max-width: 240px; }"),
    tags$style(type="text/css", ".span4 { max-width: 290px; }"),
    tags$style(type="text/css", ".well { max-width: 280px; }")
  ),

  titlePanel("Old Faithful Geyser Data"),
  div(
    style = "display:flex; align-items:flex-start",
    wellPanel( # sidebar
      sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30),
      textInput("text", "Enter text:")
    ),
    div( # main panel
      style = "flex-grow:1; resize:horizontal; overflow: hidden",
      plotOutput("distPlot")
    )
  )
)

server <- function(input, output) {
  output$distPlot <- renderPlot({
    x    <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
}

shinyApp(ui = ui, server = server)


问:
How many wiki instances to install?
I've been asked to install Mediawiki to house documentation for a company intranet. Furthermore, I've been asked to install several instances - one per contributing group: non-technical users get one, developers one, management one, etc. The idea is to provide separate web spaces for each group. Is there a way to achieve separation within one instance?

答:
It would be possible to have several MediaWikis hooked together as a "wiki family" or "wiki farm". However I have to agree with the other commenters that this would be overkill if everyone has access to everything, and it's not a huge group.

Namespaces "can be thought of as partitions of different types of information within the same wiki, and keep "real" content separate from user profiles, help pages, etc." You might have namespaces "Testing:", "Dev:", "Mgmt:", "Users:". Then you can write about each topic from those different perspectives. So a page "Testing:Logging in", "Dev:Logging in", "Mgmt:Logging in", "Users:Logging in" etc.

However when you make [[links]] in MediaWiki, you always have to put the namespace explicitly (if there is no explicit namespace, it is the "main" namespace which has no prefix). So you would have to teach each group to always put the namespace into their links and searches. It's pretty annoying. If you are insistent on using an approach like namespaces, I would recommend PmWiki. Its "namespace" feature is called WikiGroups. Creating a "namespace" is as simple as creating a link, and more importantly, if you are on a page in a particular name, by default links you make to other pages will be in that same namespace. If you want to link to a page in a different namespace you have to put it explicitly. So that is a big plus for users.

But you certainly don't need to go to namespaces to organise content in MediaWiki. You can use categories and/or templates to group content. If you are likely to have more than one group writing on the same topic, though, it's likely you'll have page name clashes. You could just get everyone to write on the same page, separating the different author groups by sections, e.g. ==Users== ==Testing== ==Dev== ==Management==.

To be honest, from what you have described I would really just use PmWiki. It is quite simple and effective.

ContentLicense: CC BY-SA 2.5

Title: How many wiki instances to install?

LastEditorDisplayName: nzpcmad


问:
XYChart.Data getNode() is null
I try to get node of an XYChart.Data, but it is null.

```<code>var a = new XYChart.Data<Number, Number>(10, 10);

if(a.getNode()==null){ System.out.println("true"); }
</code>```

Why getNode() return null? What I do wrong?

答:
The XYChart.Data.node property has an initial value of null. If you don't set it yourself then it will be set once the data becomes part of a chart. From the documentation (emphasis mine):

The node to display for this data item. You can either create your own node and set it on the data item before you add the item to the chart. Otherwise the chart will create a node for you that has the default representation for the chart type. This node will be set as soon as the data is added to the chart. You can then get it to add mouse listeners etc. Charts will do their best to position and size the node appropriately, for example on a Line or Scatter chart this node will be positioned centered on the data values position. For a bar chart this is positioned and resized as the bar for this data item.

If you need to do something with the default Node, you can add a listener to the property (before adding the data to a chart) to be notified of when it becomes non-null.

```<code>data.nodeProperty().addListener((observable, oldValue, newValue) -> {
    if (newValue != null) {
        // do something...
    }
});
</code>```

Or get the Node after you've added the data to a chart.

Title: XYChart.Data getNode() is null

Body:
I try to get node of an XYChart.Data, but it is null.

var a = new XYChart.Data<Number, Number>(10, 10);

if(a.getNode()==null){ System.out.println("true"); }

Why getNode() return null? What I do wrong?

Body:
The XYChart.Data.node property has an initial value of null. If you don't set it yourself then it will be set once the data becomes part of a chart. From the documentation (emphasis mine):

The node to display for this data item. You can either create your own node and set it on the data item before you add the item to the chart. Otherwise the chart will create a node for you that has the default representation for the chart type. This node will be set as soon as the data is added to the chart. You can then get it to add mouse listeners etc. Charts will do their best to position and size the node appropriately, for example on a Line or Scatter chart this node will be positioned centered on the data values position. For a bar chart this is positioned and resized as the bar for this data item.

If you need to do something with the default Node, you can add a listener to the property (before adding the data to a chart) to be notified of when it becomes non-null.

data.nodeProperty().addListener((observable, oldValue, newValue) -> {
    if (newValue != null) {
        // do something...
    }
});

Or get the Node after you've added the data to a chart.


问:
Frame by frame forward and backward
I am trying to set properties on a video where arrowLeft keypress is -1 frame and arrowright keypress is +1 frame, but I not able to prevent default behavior.

I've tried using e.preventDefautl() e.stopPropagation and return false.

```<code><video id="video_1" class="video" controls class="video" width="800" height="600" mediagroup="videoMG1" autobuffer preload >
    <source src="{{movie["url"]}}"  />
</video>
</code>```

```<code>var video = document.getElementById("video_1");

video.addEventListener("keypress", function(e){
  return false;
});
video.addEventListener("keyup", function(e){
  return false;
});
var video2 = VideoFrame({
    id: 'video_1',
    frameRate: 25.00,
    callback: function(response) {
        console.log(response);
    }
});

video.addEventListener("keydown", function(e){
  e.preventDefault()
  e.stopPropagation()
  debugger;
  if( e.KeyCode == 39 ){
    console.log("backward")
    video.seekBackward(1)
  }else if( e.KeyCode == 37) {
    console.log("forwrd")
    video.seekForward(1)
  }
  return false;
});
</code>```

When I enter the debugger, the video has already process the keypressed and moved forward 7 seconds instead of a frame as I would like to.

Thanks for your help !

答:
This is caused by the standard controls displayed by the browser itself.

The only way to get around this is deactivating it completely using:

```<code>video.controls=false;
</code>```

Furthermore you're calling the seekBackward() and seekForward() methods on the wrong object. I assume you're using the VideoFrame library, do you?

At the moment you're doing it like this

```<code>video.seekBackward(1);
</code>```

This is the html5 video element itself - you need to use the VideoFrame object, video2 in your case.

```<code>video2.seekBackward(1);
</code>```

Here's the full code:

```<code><html>
  <body>
    <script type="text/javascript" src="VideoFrame.min.js"></script>
    <video id="video_1" class="video" controls class="video" width="800" height="600" mediagroup="videoMG1" autobuffer preload>
            <source src="myVideo.mp4"  />
        </video>
    <div id="videoControls">
      <button type="button" id="playPause">⏵</button>
      <button type="button" id="mute">🔊</button>
      <input type="range" id="volumeBar" min="0" max="1" step="0.1" value="1">
    </div>
    <script>
      var video = document.getElementById("video_1");
      var video2 = VideoFrame({
        id: 'video_1',
        frameRate: 25.00,
        callback: function(response) {
          console.log(response);
        }
      });
      video.controls = false;
      video.addEventListener("keydown", function(e) {
        console.log("asd", e.keyCode)
        if (e.keyCode == 39) {
          console.log("backward")
          video2.seekBackward(1)
        } else if (e.KeyCode == 37) {
          console.log("forwrd")
          video2.seekForward(1)
        }
        return false;
      });

      document.getElementById("playPause").addEventListener("click", function() {
        if (video.paused == true) {
          video.play();
          this.innerHTML = "⏸";
        } else {
          video.pause();
          this.innerHTML = "⏵";
        }
      });

      document.getElementById("mute").addEventListener("click", function() {
        if (video.muted == false) {
          video.muted = true;
          this.innerHTML = "🔇";
        } else {
          video.muted = false;
          this.innerHTML = "🔊";
        }
      });

      document.getElementById("volumeBar").addEventListener("input", function() {
        video.volume = volumeBar.value;
      });

    </script>
  </body>
</html>
</code>```

Title: Frame by frame forward and backward

Body:
I am trying to set properties on a video where arrowLeft keypress is -1 frame and arrowright keypress is +1 frame, but I not able to prevent default behavior.

I've tried using e.preventDefautl() e.stopPropagation and return false.

<video id="video_1" class="video" controls class="video" width="800" height="600" mediagroup="videoMG1" autobuffer preload >
    <source src="{{movie["url"]}}"  />
</video>

var video = document.getElementById("video_1");

video.addEventListener("keypress", function(e){
  return false;
});
video.addEventListener("keyup", function(e){
  return false;
});
var video2 = VideoFrame({
    id: 'video_1',
    frameRate: 25.00,
    callback: function(response) {
        console.log(response);
    }
});

video.addEventListener("keydown", function(e){
  e.preventDefault()
  e.stopPropagation()
  debugger;
  if( e.KeyCode == 39 ){
    console.log("backward")
    video.seekBackward(1)
  }else if( e.KeyCode == 37) {
    console.log("forwrd")
    video.seekForward(1)
  }
  return false;
});

When I enter the debugger, the video has already process the keypressed and moved forward 7 seconds instead of a frame as I would like to.

Thanks for your help !

Body:
This is caused by the standard controls displayed by the browser itself.

The only way to get around this is deactivating it completely using:

video.controls=false;

Furthermore you're calling the seekBackward() and seekForward() methods on the wrong object. I assume you're using the VideoFrame library, do you?

At the moment you're doing it like this

video.seekBackward(1);

This is the html5 video element itself - you need to use the VideoFrame object, video2 in your case.

video2.seekBackward(1);

Here's the full code:

<html>
  <body>
    <script type="text/javascript" src="VideoFrame.min.js"></script>
    <video id="video_1" class="video" controls class="video" width="800" height="600" mediagroup="videoMG1" autobuffer preload>
            <source src="myVideo.mp4"  />
        </video>
    <div id="videoControls">
      <button type="button" id="playPause">&#9205;</button>
      <button type="button" id="mute">&#128266;</button>
      <input type="range" id="volumeBar" min="0" max="1" step="0.1" value="1">
    </div>
    <script>
      var video = document.getElementById("video_1");
      var video2 = VideoFrame({
        id: 'video_1',
        frameRate: 25.00,
        callback: function(response) {
          console.log(response);
        }
      });
      video.controls = false;
      video.addEventListener("keydown", function(e) {
        console.log("asd", e.keyCode)
        if (e.keyCode == 39) {
          console.log("backward")
          video2.seekBackward(1)
        } else if (e.KeyCode == 37) {
          console.log("forwrd")
          video2.seekForward(1)
        }
        return false;
      });

      document.getElementById("playPause").addEventListener("click", function() {
        if (video.paused == true) {
          video.play();
          this.innerHTML = "&#9208;";
        } else {
          video.pause();
          this.innerHTML = "&#9205;";
        }
      });

      document.getElementById("mute").addEventListener("click", function() {
        if (video.muted == false) {
          video.muted = true;
          this.innerHTML = "&#128263;";
        } else {
          video.muted = false;
          this.innerHTML = "&#128266;";
        }
      });

      document.getElementById("volumeBar").addEventListener("input", function() {
        video.volume = volumeBar.value;
      });

    </script>
  </body>
</html>


问:
Having Problem Installing Pyopencl on Windows 10 Machine Using Pip
i am trying to install pyopencl with Python but i am getting the following console output

please help me solve this issue I have already included the opencl.lib path to my env variables.

```<code>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:c:\users\mihir\appdata\local\programs\python\python36\libs /LIBPATH:c:\users\mihir\appdata\local\programs\python\python36\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\amd64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.10240.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\8.1\lib\winv6.3\um\x64" OpenCL.lib /EXPORT:PyInit__cl build\temp.win-amd64-3.6\Release\src/wrap_constants.obj build\temp.win-amd64-3.6\Release\src/wrap_cl.obj build\temp.win-amd64-3.6\Release\src/wrap_cl_part_1.obj build\temp.win-amd64-3.6\Release\src/wrap_cl_part_2.obj build\temp.win-amd64-3.6\Release\src/wrap_mempool.obj build\temp.win-amd64-3.6\Release\src/bitlog.obj /OUT:build\lib.win-amd64-3.6\pyopencl\_cl.cp36-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.6\Release\src\_cl.cp36-win_amd64.lib
    LINK : fatal error LNK1181: cannot open input file 'OpenCL.lib'
    error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\link.exe' failed with exit status 1181

    ----------------------------------------
Command "c:\users\mihir\appdata\local\programs\python\python36\python.exe -u -c "import setuptools, tokenize;__file__='C:\\Users\\MIHIR\\AppData\\Local\\Temp\\pip-install-82kaln2a\\pyopencl\\setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\MIHIR\AppData\Local\Temp\pip-record-jp0yo2ti\install-record.txt --single-version-externally-managed --compile" failed with error code 1 in C:\Users\MIHIR\AppData\Local\Temp\pip-install-82kaln2a\pyopencl\
</code>```

答:
I faced same problem and i couldn't install pyopencl. I was using python 3.7 in 64 bit windows. So i used pyopencl‑2018.2.5+cl21‑cp37‑cp37m‑win_amd64.whl version. But unfortunately it didn't work. </p>

<p>So i tried with pyopencl‑2018.2.5+cl21‑cp37‑cp37m‑win32.whl version and then it installed successfully. </p>

Body:
i am trying to install pyopencl with Python but i am getting the following console output

please help me solve this issue I have already included the opencl.lib path to my env variables.

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:c:\users\mihir\appdata\local\programs\python\python36\libs /LIBPATH:c:\users\mihir\appdata\local\programs\python\python36\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\amd64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.10240.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\8.1\lib\winv6.3\um\x64" OpenCL.lib /EXPORT:PyInit__cl build\temp.win-amd64-3.6\Release\src/wrap_constants.obj build\temp.win-amd64-3.6\Release\src/wrap_cl.obj build\temp.win-amd64-3.6\Release\src/wrap_cl_part_1.obj build\temp.win-amd64-3.6\Release\src/wrap_cl_part_2.obj build\temp.win-amd64-3.6\Release\src/wrap_mempool.obj build\temp.win-amd64-3.6\Release\src/bitlog.obj /OUT:build\lib.win-amd64-3.6\pyopencl\_cl.cp36-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.6\Release\src\_cl.cp36-win_amd64.lib
    LINK : fatal error LNK1181: cannot open input file 'OpenCL.lib'
    error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\link.exe' failed with exit status 1181

    ----------------------------------------
Command "c:\users\mihir\appdata\local\programs\python\python36\python.exe -u -c "import setuptools, tokenize;__file__='C:\\Users\\MIHIR\\AppData\\Local\\Temp\\pip-install-82kaln2a\\pyopencl\\setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\MIHIR\AppData\Local\Temp\pip-record-jp0yo2ti\install-record.txt --single-version-externally-managed --compile" failed with error code 1 in C:\Users\MIHIR\AppData\Local\Temp\pip-install-82kaln2a\pyopencl\

Body:
I faced same problem and i couldn't install pyopencl. I was using python 3.7 in 64 bit windows. So i used pyopencl‑2018.2.5+cl21‑cp37‑cp37m‑win_amd64.whl version. But unfortunately it didn't work.

So i tried with pyopencl‑2018.2.5+cl21‑cp37‑cp37m‑win32.whl version and then it installed successfully.


问:
How can I get the value of a radio button inside a google visualization table
I have a table that I build using a chart wrapper as follows:

```<code>var rightWrapper;
function drawVisualization() {
  rightWrapper = new google.visualization.ChartWrapper({
  "chartType": "Table",
  'dataSourceUrl':'https://docs.google.com/spreadsheets/d/1I3N5DtdXGWFootaOCQM201K_ao2ZPWSWyw9_l7QcwQg/gviz/tq?sheet=User_my_crew&headers=1',
  'containerId':'target_table_div',
  'query':'SELECT A,B,C,D',
  'options': { 'width': 700, 'height': 500, 'allowHtml': true }
  });

  google.visualization.events.addListener(rightWrapper, 'ready', onRightReady);

  rightWrapper.draw();

  function onRightReady() {
    google.visualization.events.addListener(rightWrapper.getChart(), 'select', rightSelectionHandler);
  }

  function rightSelectionHandler() {
    var selection = rightWrapper.getChart().getSelection();
    if (selection.length == 1) {
      var item = selection[0];
      if (item.row != null) {
        alert("selected row " + item.row);
        var value = (rightWrapper.getSnapshot().getDataTable().getValue(item.row,3));
        alert(value);
      }
    }
  }
}
</code>```

And in that column 3, I have html to build radio buttons.  Unfortunately, the actual html is stored, and I don't seem to have a way of polling to find out which radio button is now checked (the getValue listed in the code above always shows me just the html that was used to build the radio buttons, not which one is now "checked").

Unfortunately, it appears any clicks inside that table have to be picked up with the select listener, and the select listener doesn't relay any information beyond the row and column selected.  I tried building in change and click functions, and putting s around my radio buttons, too.  For instance:

```<code>$("#radio").click(function(){  //also tried with .change
  alert("working");
});
</code>```

That never fires, even if I disable my original listener.

So, how can I know what radio button my user selected?

Note: I do need the radio buttons inside the table, as every single row of the table has its own radio buttons to provide me different information on each.

答:
you don't need the form, you just need to wait for the chart's 'ready' event,

before assigning the change event.

see following working snippet,

select a radio to see the name and value...

google.charts.load('current', {
  packages: ['controls', 'table']
}).then(function () {
  var rightWrapper = new google.visualization.ChartWrapper({
    chartType: 'Table',
    dataSourceUrl: 'https://docs.google.com/spreadsheets/d/1I3N5DtdXGWFootaOCQM201K_ao2ZPWSWyw9_l7QcwQg/gviz/tq?sheet=User_my_crew&headers=1',
    containerId: 'target_table_div',
    query: 'SELECT A,B,C,D',
    options: { 'width': 700, 'height': 500, 'allowHtml': true }
  });

  google.visualization.events.addListener(rightWrapper, 'ready', onRightReady);

  rightWrapper.draw();

  function onRightReady() {
    $('input[type="radio"]').on('change', calcForm2);
  }
});

function calcForm2(sender) {
  console.log(sender.target.name, sender.target.value);
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="target_table_div"></div></code>```

Body:
I have a table that I build using a chart wrapper as follows:

var rightWrapper;
function drawVisualization() {
  rightWrapper = new google.visualization.ChartWrapper({
  "chartType": "Table",
  'dataSourceUrl':'https://docs.google.com/spreadsheets/d/1I3N5DtdXGWFootaOCQM201K_ao2ZPWSWyw9_l7QcwQg/gviz/tq?sheet=User_my_crew&headers=1',
  'containerId':'target_table_div',
  'query':'SELECT A,B,C,D',
  'options': { 'width': 700, 'height': 500, 'allowHtml': true }
  });

  google.visualization.events.addListener(rightWrapper, 'ready', onRightReady);

  rightWrapper.draw();

  function onRightReady() {
    google.visualization.events.addListener(rightWrapper.getChart(), 'select', rightSelectionHandler);
  }

  function rightSelectionHandler() {
    var selection = rightWrapper.getChart().getSelection();
    if (selection.length == 1) {
      var item = selection[0];
      if (item.row != null) {
        alert("selected row " + item.row);
        var value = (rightWrapper.getSnapshot().getDataTable().getValue(item.row,3));
        alert(value);
      }
    }
  }
}

And in that column 3, I have html to build radio buttons.  Unfortunately, the actual html is stored, and I don't seem to have a way of polling to find out which radio button is now checked (the getValue listed in the code above always shows me just the html that was used to build the radio buttons, not which one is now "checked").

Unfortunately, it appears any clicks inside that table have to be picked up with the select listener, and the select listener doesn't relay any information beyond the row and column selected.  I tried building in change and click functions, and putting s around my radio buttons, too.  For instance:

$("#radio").click(function(){  //also tried with .change
  alert("working");
});

That never fires, even if I disable my original listener.

So, how can I know what radio button my user selected?

Note: I do need the radio buttons inside the table, as every single row of the table has its own radio buttons to provide me different information on each.

Body:
you don't need the form, you just need to wait for the chart's 'ready' event,

before assigning the change event.

see following working snippet,

select a radio to see the name and value...

google.charts.load('current', {
  packages: ['controls', 'table']
}).then(function () {
  var rightWrapper = new google.visualization.ChartWrapper({
    chartType: 'Table',
    dataSourceUrl: 'https://docs.google.com/spreadsheets/d/1I3N5DtdXGWFootaOCQM201K_ao2ZPWSWyw9_l7QcwQg/gviz/tq?sheet=User_my_crew&headers=1',
    containerId: 'target_table_div',
    query: 'SELECT A,B,C,D',
    options: { 'width': 700, 'height': 500, 'allowHtml': true }
  });

  google.visualization.events.addListener(rightWrapper, 'ready', onRightReady);

  rightWrapper.draw();

  function onRightReady() {
    $('input[type="radio"]').on('change', calcForm2);
  }
});

function calcForm2(sender) {
  console.log(sender.target.name, sender.target.value);
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="target_table_div"></div>


问:
Explode PHP String
I need some help, is it possible to explode like this?
I have a string 45-test-sample, is it possible to have

```<code>[0]=>string == "45"
[1]=>string == "test-sample"
</code>```

How can it be done?

答:
Try with exact output using list.

```<code><?php
  $str = "45-test-sample";
  list($a,$b) = explode('-', $str, 2);
  $arr=Array();
  $arr=['0'=>"String == ".$a,'1'=>"String == ".$b];
  print_r($arr);
</code>```

?>

Output:

```<code>Array
(
   [0] => String == 45
   [1] => String == test-sample
)
</code>```

DEMO

ContentLicense: CC BY-SA 3.0

Title: Explode PHP String

Body:
I need some help, is it possible to explode like this?
I have a string 45-test-sample, is it possible to have

[0]=>string == "45"
[1]=>string == "test-sample"

How can it be done?

Body:
Try with exact output using list.

<?php
  $str = "45-test-sample";
  list($a,$b) = explode('-', $str, 2);
  $arr=Array();
  $arr=['0'=>"String == ".$a,'1'=>"String == ".$b];
  print_r($arr);

?>

Output:

Array
(
   [0] => String == 45
   [1] => String == test-sample
)

DEMO


问:
when using exporting(highchart) in angular 7 got the the error
using exporting(highchart) getting below error:
ERROR in src/app/desktop/module/dashboard/dashboard.module.ts(24,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'typeof import("C:/website/UI_Dashboard/node_modules/highchart
s/modules/exporting.src")' has no compatible call signatures.

in the module:

```<code>import {ChartModule, HIGHCHARTS_MODULES} from 'angular-highcharts';
import * as more from 'highcharts/highcharts-more.src';
import * as highcharts from 'highcharts';
import * as exporting from 'highcharts/modules/exporting.src';
import * as offline from 'highcharts/modules/offline-exporting';
exporting(highcharts);
offline(highcharts);
</code>```

what should I do for solving this issue?

答:
Have you tried with import exporting from 'highcharts/modules/exporting.src';?

It's the suggested way of module working as documented in the official Highcharts wrapper for Angular - https://github.com/highcharts/highcharts-angular#core

You should also load all Highcharts related files as src or minified - mixing might cause some TS issues.

An import path for src version of Highcharts core is 'highcharts/highcharts.src'.

Also (I'm not sure if this applies here since the code might not be complete), highcharts-more needs to be initialized as any other module. Usually it is loaded before other modules - initialization order is rarely important (some series types are based on optional modules) and you will get an error if the order is wrong, so it's important to test this.

Body:
using exporting(highchart) getting below error:
ERROR in src/app/desktop/module/dashboard/dashboard.module.ts(24,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'typeof import("C:/website/UI_Dashboard/node_modules/highchart
s/modules/exporting.src")' has no compatible call signatures.

in the module:

import {ChartModule, HIGHCHARTS_MODULES} from 'angular-highcharts';
import * as more from 'highcharts/highcharts-more.src';
import * as highcharts from 'highcharts';
import * as exporting from 'highcharts/modules/exporting.src';
import * as offline from 'highcharts/modules/offline-exporting';
exporting(highcharts);
offline(highcharts);

what should I do for solving this issue?


问:
How to fix using loopback 4 (translate rest to graphql) : OPTIONS http://localhost:3001/graphql 405 (Method Not Allowed)
I am connecting the postgresql with loopback 4 and call the API on frontend using axios + restful and it was sucessfully done.

But when I tried to connect postgresql with loopback 4 and call the API on frontend using axios + graphql, it gives these 3 errors on browser's console:

OPTIONS http://localhost:3001/graphql 405 (Method Not Allowed)

Access to XMLHttpRequest at 'http://localhost:3001/graphql' from origin 'http://localhost:8081' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Error: Network Error
at createError (createError.js?2d83:16)
at XMLHttpRequest.handleError (xhr.js?b50d:87)

I tried to search and read on googles, but most of them are not using loopback.

I followed this tutorial,

https://v4.loopback.io/getting-started-oasgraph.html

https://www.thepolyglotdeveloper.com/2019/01/query-graphql-api-vuejs-axios/

But still not resolved.

Here is my source code modification, Home.vue.

```<code><template>
    <div>
    </div>
</template>

<script>
    import axios from "axios";
    export default {
        name: "HelloWorld",
        async mounted() {
            try {
                var result = await axios({
                    method: "POST",
                    url: "http://localhost:3001/graphql",
                    data: {
                        query: `
                            {
                                organizations {
                                  organizationId
                                  organizationName
                                }
                            }
                        `
                    }
                });
                console.log("kk", result);

            } catch (error) {
                console.error(error);
            }
        }
    }
</script>

<style scoped></style>
</code>```

I expect the output inside console should be the API content. Is there any additional settings which I missed out?

答:
This looks to me like the request is denied because of CORS.

I checked the source code of oasgraph-cli, CORS is not allowed by default. Fortunately there is a CLI option to enable support for cross-origin requests.

The following command should fix the problem for you:

```<code>oasgraph --cors [path to saved OAS]
</code>```

The CLI option is defined here:

```<code>.option('--cors', 'enable Cross-origin resource sharing (CORS)')
</code>```

And applies the following change to the Express application:

if (program.cors) {
  app.use(cors());
}
```

Body:
I am connecting the postgresql with loopback 4 and call the API on frontend using axios + restful and it was sucessfully done.

But when I tried to connect postgresql with loopback 4 and call the API on frontend using axios + graphql, it gives these 3 errors on browser's console:

OPTIONS http://localhost:3001/graphql 405 (Method Not Allowed)

Access to XMLHttpRequest at 'http://localhost:3001/graphql' from origin 'http://localhost:8081' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Error: Network Error
at createError (createError.js?2d83:16)
at XMLHttpRequest.handleError (xhr.js?b50d:87)

I tried to search and read on googles, but most of them are not using loopback.

I followed this tutorial,

https://v4.loopback.io/getting-started-oasgraph.html

https://www.thepolyglotdeveloper.com/2019/01/query-graphql-api-vuejs-axios/

But still not resolved.

Here is my source code modification, Home.vue.

<template>

</template>

I expect the output inside console should be the API content. Is there any additional settings which I missed out?

Body:
This looks to me like the request is denied because of CORS.

I checked the source code of oasgraph-cli, CORS is not allowed by default. Fortunately there is a CLI option to enable support for cross-origin requests.

The following command should fix the problem for you:

oasgraph --cors [path to saved OAS]

The CLI option is defined here:

.option('--cors', 'enable Cross-origin resource sharing (CORS)')

And applies the following change to the Express application:

if (program.cors) {
  app.use(cors());
}