问:
implementing websocket server by nodejs on shared cpanel host
I have acquired a shared host with a cpanel which supports nodejs. I can define a node.js app through "Setup Node.js App".

I want to make a websocket. They have opened 2088 Port for me.

This is my websocket server code:

```<code>const http = require('http');
const WebSocket = require('ws');

const server = http.createServer();
const wss = new WebSocket.Server({ server });

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });

  ws.send('something');
});

server.listen(2088);
</code>```

Well, I run my code and then I send this request from client to server:

```<code>socket = new WebSocket('ws://mydomain.com:2088');

socket.addEventListener('open', function (event) {
    socket.send('Hello Server!');
});

socket.addEventListener('message', function (event) {
    console.log('Message from server ', event.data);
});
</code>```

But, I keep receiving a timeout error and I can not connect to the websocket server.

It appears that making a websocket server on a shared cpanel host that is able to listen on a specific port, is a little bit different from the usual.

I have combed through the internet and all I got on cpanel nodejs was how to build a node.js app using cpanel menus. I couldn't find any explanation on how to make a websocket on shared cpanel host. All of the sources say that it is possible to make a websocket with a nodejs which is offered on cpanel.

Now, has anyone ever had a shared host with nodejs features? And run websocket on it?

The admins who have sold the host to me, are complete idiots, know nothing about this, and can not help me...

Thanks for your help in advance.

UPDATE:

How to run Node.js and python in shared hosts differs from the way they are run in vps. According to what I found out, the phusion passenger is used in shared hosts. The problem I'm having can be solved by someone who has worked on shared hosts with Nodejs and knows about the way phusion passenger works.

答:
For a node application deployed from the cPanel UI, cPanel relies on Passenger to manage deployment. When a WebSockets connection request is sent, the client sends an HTTP request to "upgrade" via the Connection header in the request. Passenger responds to standard HTTP requests, but doesn't do anything with the Connection header, so the WebSockets request is effectively ignored. You can actually see this happening if you open the JS debugger inside your browser and inspect the WebSockets target resource.

Phusion has a WebSockets demo posted to GitHub that uses socket.io. In the demo's README, it states that WebSockets doesn't work correctly inside of Passenger, so instead it resorts to using HTTP long polling as a fallback. However, this fallback is a feature engineered into socket.io and for it to work correctly, Passenger has to be configured to use sticky sessions, which is an option not currently exposed to the UI in cPanel.

<s>If you want to use node as a WebSockets server, you're going to need to run it outside of Passenger, and thus will most-likely need to get out of the shared hosting environment. Running it on cPanel is possible, but not without elevated shell privileges for your account.</s>

Edit:

Your question really bothered me and so I spent another couple of hours working on it. If you really really want to run a node WebSockets server from cPanel, you can accomplish this by calling your server app using forever from a parent app that you've registered in the cPanel Application Manager. The parent app will execute from Passenger, and then your server app will execute outside of Passenger via forever. Passenger will complain about using the Node Cluster module, but it will still work.

Be sure that your parent app responds to HTTP requests, because you'll need to send at least one request to instantiate it in Passenger.

Body:
I have acquired a shared host with a cpanel which supports nodejs. I can define a node.js app through "Setup Node.js App".

I want to make a websocket. They have opened 2088 Port for me.

This is my websocket server code:

const http = require('http');
const WebSocket = require('ws');

const server = http.createServer();
const wss = new WebSocket.Server({ server });

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });

  ws.send('something');
});

server.listen(2088);

Well, I run my code and then I send this request from client to server:

socket = new WebSocket('ws://mydomain.com:2088');

socket.addEventListener('open', function (event) {
    socket.send('Hello Server!');
});

socket.addEventListener('message', function (event) {
    console.log('Message from server ', event.data);
});

But, I keep receiving a timeout error and I can not connect to the websocket server.

It appears that making a websocket server on a shared cpanel host that is able to listen on a specific port, is a little bit different from the usual.

I have combed through the internet and all I got on cpanel nodejs was how to build a node.js app using cpanel menus. I couldn't find any explanation on how to make a websocket on shared cpanel host. All of the sources say that it is possible to make a websocket with a nodejs which is offered on cpanel.

Now, has anyone ever had a shared host with nodejs features? And run websocket on it?

The admins who have sold the host to me, are complete idiots, know nothing about this, and can not help me...

Thanks for your help in advance.

UPDATE:

How to run Node.js and python in shared hosts differs from the way they are run in vps. According to what I found out, the phusion passenger is used in shared hosts. The problem I'm having can be solved by someone who has worked on shared hosts with Nodejs and knows about the way phusion passenger works.


来源: stackexchange

问:
Angular: Can't bind to 'file' since it isn't a known property of 'input'
I've two input elements in my component.html

```<code><input type="file" ngf [(files)]="files" multiple  />
  <input type="file" ngf [(file)]="file" />
</code>```

The first one is working perfectly whereas the second one is resulting in error Can't bind to 'file' since it isn't a known property of 'input'. I've imported ngfModule from "angular-file" in my module.ts file. I'm following this website https://www.npmjs.com/package/angular-file and I couldn't figure out what is the problem? How to fix this error?

答:
It should be like this-</p>

```<code><input type="file" ngf [(files)]="files" multiple  />
<input type="file" ngf [(files)]="file" />
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I've two input elements in my component.html

<input type="file" ngf [(files)]="files" multiple  />
  <input type="file" ngf [(file)]="file" />

The first one is working perfectly whereas the second one is resulting in error Can't bind to 'file' since it isn't a known property of 'input'. I've imported ngfModule from "angular-file" in my module.ts file. I'm following this website https://www.npmjs.com/package/angular-file and I couldn't figure out what is the problem? How to fix this error?

Body:
It should be like this-

<input type="file" ngf [(files)]="files" multiple  />
<input type="file" ngf [(files)]="file" />


问:
Could NOT find Protobuf (missing: Protobuf_PROTOC_EXECUTABLE)
When I am doing a cmake in the build directory of the project I am getting this error. Initially I got a

protobuf-config.cmake not found

error. So I gave a path of the protobuf-config.cmake file to Protobuf_DIR. Later it started to show this new error:

CMake Error at
  /opt/cmake/share/cmake-3.13/Modules/FindPackageHandleStandardArgs.cmake:137
  (message):   Could NOT find Protobuf (missing:
  Protobuf_PROTOC_EXECUTABLE)

(found   suitable version "3.6.1", minimum required is "3.0.0")

I am also attaching the error log file:
https://drive.google.com/open?id=1y7BZ6lDBtxvla7r-o188xM_FjwLqwhCx

I am doing this on Ubuntu-18 with cmake version: 3.13 and protobuf version: 3.6.1

答:
Hy,

list your protobuf libraries with sudo apt list | grep protobuf it should tell you what it will install by default. Run protoc --version so that you see what is recognized by default now. And after that get a version from github if needed build it and install it (this should not take to long). Then run protoc --version again.


问:
Spike: error while loading shared libraries: libriscv.so
I tried to execute spike this way by navigating to the folder the executable is in:

cd ~/riscv-tools/riscv-isa-sim/build
./spike
I get this error message:

./spike: error while loading shared libraries: libriscv.so: cannot open shared object file: No such file or directory
It is significant that the file it claims to not find is in the same directory as the spike executable (in the build directory) - any help?

答:
The usual way is to execute Spike it to execute it from the installed location, e.g. install it like this:

```<code>cd riscv-isa-sim
mkdir build
cd build
../configure --prefix=$HOME/local/riscv/spike
make
make install
</code>```

And then execute it:

```<code>~/local/riscv/spike/bin/spike ...
</code>```

No need to mess around with your LD_LIBRARY_PATH then (which really should be avoided, if possible).

ContentLicense: CC BY-SA 3.0

Body:
The usual way is to execute Spike it to execute it from the installed location, e.g. install it like this:

cd riscv-isa-sim
mkdir build
cd build
../configure --prefix=$HOME/local/riscv/spike
make
make install

And then execute it:

~/local/riscv/spike/bin/spike ...

No need to mess around with your LD_LIBRARY_PATH then (which really should be avoided, if possible).


问:
Orbit of a set of permutations
In GAP, we can find the orbit of a set of permutations easily enough:

```<code>grp := Group([ (1,2,3,4,5), (1,2,4,3) ]);;
els := Elements(grp);;
O := Orbit(grp, els{[1,2,3,4]}, OnSets);

[ [ (), (2,3,5,4), (2,4,5,3), (2,5)(3,4) ], [ (), (1,3)(4,5), (1,4,3,5), (1,5,3,4) ],
  [ (), (1,2,5,4), (1,4,5,2), (1,5)(2,4) ], [ (), (1,2)(3,5), (1,3,2,5), (1,5,2,3) ],
  [ (), (1,2,4,3), (1,3,4,2), (1,4)(2,3) ] ]
</code>```

I'd like to do this in Sage (preferably without invoking the GAP interface). In the documentation, I found the following: http://doc.sagemath.org/html/en/reference/groups/sage/groups/perm_gps/permgroup.html#sage.groups.perm_gps.permgroup.PermutationGroup_generic.orbit

They provide the following "OnSets" example:

```<code>sage: S3 = groups.permutation.Symmetric(3)
sage: S3.orbit((1,2), action = "OnSets")
({1, 2}, {2, 3}, {1, 3})
</code>```

So I tried the following:

```<code>grp = PermutationGroup([ '(1,2,3,4,5)', '(1,2,4,3)' ])
els = list(grp)
grp.orbit(els[:4], action = "OnSets")

TypeError: unhashable type: 'list'
</code>```

Does anyone have any idea how to compute this properly? Currently, I'm getting around this using gap.eval:

```<code>gap.eval("grp := Group([ (1,2,3,4,5), (1,2,4,3) ])")
gap.eval("els := Elements(grp)")
gap.eval("test_orbit := Orbit(grp, els{[1,2,3,4]}, OnSets)")
O = gap.new("test_orbit")
</code>```

Now any calculation I do using 'O' is incredibly slow, so I'd like to try do everything in Sage, or somehow convert 'O' into a proper Sage object that's quick to work with.

答:
In the example the set in question is a subgroup; then a better way is to build an action on cosets.

Also, we don't recomment using GAP pexpect interface, use libgap instead.
Then your example may be written as follows (I only used abother way to create the subset of permutations to act on):

```<code>sage: grp = libgap(PermutationGroup([ '(1,2,3,4,5)', '(1,2,4,3)' ])); grp
Group([ (1,2,3,4,5), (1,2,4,3) ])
sage: s=grp.Stabilizer(1)
sage: grp.Orbit(s.Elements(),libgap.OnSets)
[ [ (), (2,3,5,4), (2,4,5,3), (2,5)(3,4) ], [ (), (1,3)(4,5), (1,4,3,5), (1,5,3,4) ], [ (), (1,2,5,4), (1,4,5,2), (1,5)(2,4) ], [ (), (1,2)(3,5), (1,3,2,5), (1,5,2,3) ], [ (), (1,2,4,3), (1,3,4,2), (1,4)(2,3) ] ]
</code>```

Title: Orbit of a set of permutations

Body:
In GAP, we can find the orbit of a set of permutations easily enough:

grp := Group([ (1,2,3,4,5), (1,2,4,3) ]);;
els := Elements(grp);;
O := Orbit(grp, els{[1,2,3,4]}, OnSets);

[ [ (), (2,3,5,4), (2,4,5,3), (2,5)(3,4) ], [ (), (1,3)(4,5), (1,4,3,5), (1,5,3,4) ],
  [ (), (1,2,5,4), (1,4,5,2), (1,5)(2,4) ], [ (), (1,2)(3,5), (1,3,2,5), (1,5,2,3) ],
  [ (), (1,2,4,3), (1,3,4,2), (1,4)(2,3) ] ]

I'd like to do this in Sage (preferably without invoking the GAP interface). In the documentation, I found the following: http://doc.sagemath.org/html/en/reference/groups/sage/groups/perm_gps/permgroup.html#sage.groups.perm_gps.permgroup.PermutationGroup_generic.orbit

They provide the following "OnSets" example:

sage: S3 = groups.permutation.Symmetric(3)
sage: S3.orbit((1,2), action = "OnSets")
({1, 2}, {2, 3}, {1, 3})

So I tried the following:

grp = PermutationGroup([ '(1,2,3,4,5)', '(1,2,4,3)' ])
els = list(grp)
grp.orbit(els[:4], action = "OnSets")

TypeError: unhashable type: 'list'

Does anyone have any idea how to compute this properly? Currently, I'm getting around this using gap.eval:

gap.eval("grp := Group([ (1,2,3,4,5), (1,2,4,3) ])")
gap.eval("els := Elements(grp)")
gap.eval("test_orbit := Orbit(grp, els{[1,2,3,4]}, OnSets)")
O = gap.new("test_orbit")

Now any calculation I do using 'O' is incredibly slow, so I'd like to try do everything in Sage, or somehow convert 'O' into a proper Sage object that's quick to work with.

Body:
In the example the set in question is a subgroup; then a better way is to build an action on cosets.

Also, we don't recomment using GAP pexpect interface, use libgap instead.
Then your example may be written as follows (I only used abother way to create the subset of permutations to act on):

sage: grp = libgap(PermutationGroup([ '(1,2,3,4,5)', '(1,2,4,3)' ])); grp
Group([ (1,2,3,4,5), (1,2,4,3) ])
sage: s=grp.Stabilizer(1)
sage: grp.Orbit(s.Elements(),libgap.OnSets)
[ [ (), (2,3,5,4), (2,4,5,3), (2,5)(3,4) ], [ (), (1,3)(4,5), (1,4,3,5), (1,5,3,4) ], [ (), (1,2,5,4), (1,4,5,2), (1,5)(2,4) ], [ (), (1,2)(3,5), (1,3,2,5), (1,5,2,3) ], [ (), (1,2,4,3), (1,3,4,2), (1,4)(2,3) ] ]


问:
How do i compare the dates read from csv file, such that I will only count those post with that month?
I am currently stumped in filtering out the dates that I have retrieved from 2 CSV file via opencsv. I wish to filter out the dates by month such that I could count the number of posts of each month and display it via javaFX line chart. E.g. y-axis would be number of post, x-axis would be the month.
So far, as per my codes below, it just prints out a list of "is it not comparing". So far I have manage to convert the date to string format such that it would print out just the month, Feb, Jan, Dec, etc...

Format of the dates in csv files are:

```<code>csv file 1: Feb 14, 2020, 8:03 pm

csv file 2: 2020-01-20T16:34:57+0800
</code>```

CODE

```<code>int febCounter = 0;
int janCounter = 0;
int decCounter = 0;
String pattern = "MMM";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);

try (Reader reader = Files.newBufferedReader(Paths.get("file_path"));
            CSVReader csvReader = new CSVReader(reader);){
    String [] nextRecord;
    while((nextRecord = csvReader.readNext()) != null) {
        String retrievedate = nextRecord[2];
        Date date = sdf.parse(retrievedate);
        String strDate = sdf.format(date);
        if(strDate.equals("Feb")) {
            febCounter++;
        }
        else {
            System.out.println("it is not comparing");
        }
        System.out.println(febCounter);
    }
} catch(IOException e) {
    System.out.print("File can't be found");
}
</code>```

EXPECTED OUTPUT

```<code>Feburary: 50

January: 20

December: 10
</code>```

Current OUTPUT

```<code>it is not comparing
it is not comparing
it is not comparing
it is not comparing
</code>```

so on....

UPDATE

So I am able to fix my error, I needed to format the retrieved date twice, once is to format the date such that I would only have the month, second format is to convert the date into a string, such that "strDate.equals("Feb")" will work.

答:
Can you add a real example of the content of files?
You have two csv files, each one has a different date format.

lets strat with the first one, if you have "Feb 14, 2020, 8:03 pm" then the nextRecord variable will be :

```<code>[
    0 => "Feb 14",
    1 => "2020",
    2 => "8:03 pm",
]
</code>```

And you have to test if nextRecord[0].startWith("Feb") and not equal.

Body:
I am currently stumped in filtering out the dates that I have retrieved from 2 CSV file via opencsv. I wish to filter out the dates by month such that I could count the number of posts of each month and display it via javaFX line chart. E.g. y-axis would be number of post, x-axis would be the month.
So far, as per my codes below, it just prints out a list of "is it not comparing". So far I have manage to convert the date to string format such that it would print out just the month, Feb, Jan, Dec, etc...

Format of the dates in csv files are:

csv file 1: Feb 14, 2020, 8:03 pm

csv file 2: 2020-01-20T16:34:57+0800

CODE

int febCounter = 0;
int janCounter = 0;
int decCounter = 0;
String pattern = "MMM";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);

try (Reader reader = Files.newBufferedReader(Paths.get("file_path"));
            CSVReader csvReader = new CSVReader(reader);){
    String [] nextRecord;
    while((nextRecord = csvReader.readNext()) != null) {
        String retrievedate = nextRecord[2];
        Date date = sdf.parse(retrievedate);
        String strDate = sdf.format(date);
        if(strDate.equals("Feb")) {
            febCounter++;
        }
        else {
            System.out.println("it is not comparing");
        }
        System.out.println(febCounter);
    }
} catch(IOException e) {
    System.out.print("File can't be found");
}

EXPECTED OUTPUT

Feburary: 50

January: 20

December: 10

Current OUTPUT

it is not comparing
it is not comparing
it is not comparing
it is not comparing

so on....

UPDATE

So I am able to fix my error, I needed to format the retrieved date twice, once is to format the date such that I would only have the month, second format is to convert the date into a string, such that "strDate.equals("Feb")" will work.

Body:
Can you add a real example of the content of files?
You have two csv files, each one has a different date format.

lets strat with the first one, if you have "Feb 14, 2020, 8:03 pm" then the nextRecord variable will be :

[
    0 => "Feb 14",
    1 => "2020",
    2 => "8:03 pm",
]

And you have to test if nextRecord[0].startWith("Feb") and not equal.


问:
How do I make UILabel display outlined text?
All I want is a one pixel black border around my white UILabel text.

I got as far as subclassing UILabel with the code below, which I clumsily cobbled together from a few tangentially related online examples. And it works but it's very, very slow (except on the simulator) and I couldn't get it to center the text vertically either (so I hard-coded the y value on the last line temporarily). Ahhhh!

```<code>void ShowStringCentered(CGContextRef gc, float x, float y, const char *str) {
    CGContextSetTextDrawingMode(gc, kCGTextInvisible);
    CGContextShowTextAtPoint(gc, 0, 0, str, strlen(str));
    CGPoint pt = CGContextGetTextPosition(gc);

    CGContextSetTextDrawingMode(gc, kCGTextFillStroke);

    CGContextShowTextAtPoint(gc, x - pt.x / 2, y, str, strlen(str));
}

- (void)drawRect:(CGRect)rect{

    CGContextRef theContext = UIGraphicsGetCurrentContext();
    CGRect viewBounds = self.bounds;

    CGContextTranslateCTM(theContext, 0, viewBounds.size.height);
    CGContextScaleCTM(theContext, 1, -1);

    CGContextSelectFont (theContext, "Helvetica", viewBounds.size.height,  kCGEncodingMacRoman);

    CGContextSetRGBFillColor (theContext, 1, 1, 1, 1);
    CGContextSetRGBStrokeColor (theContext, 0, 0, 0, 1);
    CGContextSetLineWidth(theContext, 1.0);

    ShowStringCentered(theContext, rect.size.width / 2.0, 12, [[self text] cStringUsingEncoding:NSASCIIStringEncoding]);
}
</code>```

I just have a nagging feeling that I'm overlooking a simpler way to do this. Perhaps by overriding "drawTextInRect", but I can't seem to get drawTextInRect to bend to my will at all despite staring at it intently and frowning really really hard.

答:
If your goal is something like this:

Here is how I achieved it: I added a new label of a custom class as a Subview to my current UILabel (inspired by this answer).

Just copy & paste it into your project and you are good to go:

```<code>extension UILabel {
    func addTextOutline(usingColor outlineColor: UIColor, outlineWidth: CGFloat) {
        class OutlinedText: UILabel{
            var outlineWidth: CGFloat = 0
            var outlineColor: UIColor = .clear

            override public func drawText(in rect: CGRect) {
                let shadowOffset = self.shadowOffset
                let textColor = self.textColor

                let c = UIGraphicsGetCurrentContext()
                c?.setLineWidth(outlineWidth)
                c?.setLineJoin(.round)
                c?.setTextDrawingMode(.stroke)
                self.textAlignment = .center
                self.textColor = outlineColor
                super.drawText(in:rect)

                c?.setTextDrawingMode(.fill)
                self.textColor = textColor
                self.shadowOffset = CGSize(width: 0, height: 0)
                super.drawText(in:rect)

                self.shadowOffset = shadowOffset
            }
        }

        let textOutline = OutlinedText()
        let outlineTag = 9999

        if let prevTextOutline = viewWithTag(outlineTag) {
            prevTextOutline.removeFromSuperview()
        }

        textOutline.outlineColor = outlineColor
        textOutline.outlineWidth = outlineWidth
        textOutline.textColor = textColor
        textOutline.font = font
        textOutline.text = text
        textOutline.tag = outlineTag

        sizeToFit()
        addSubview(textOutline)
        textOutline.frame = CGRect(x: -(outlineWidth / 2), y: -(outlineWidth / 2),
                                   width: bounds.width + outlineWidth,
                                   height: bounds.height + outlineWidth)
    }
}
</code>```

USAGE:

```<code>yourLabel.addTextOutline(usingColor: .red, outlineWidth: 6)
</code>```

it also works for a UIButton with all its animations:

```<code>yourButton.titleLabel?.addTextOutline(usingColor: .red, outlineWidth: 6)
</code>```

ContentLicense: CC BY-SA 2.5

Body:
All I want is a one pixel black border around my white UILabel text.

I got as far as subclassing UILabel with the code below, which I clumsily cobbled together from a few tangentially related online examples. And it works but it's very, very slow (except on the simulator) and I couldn't get it to center the text vertically either (so I hard-coded the y value on the last line temporarily). Ahhhh!

void ShowStringCentered(CGContextRef gc, float x, float y, const char *str) {
    CGContextSetTextDrawingMode(gc, kCGTextInvisible);
    CGContextShowTextAtPoint(gc, 0, 0, str, strlen(str));
    CGPoint pt = CGContextGetTextPosition(gc);

    CGContextSetTextDrawingMode(gc, kCGTextFillStroke);

    CGContextShowTextAtPoint(gc, x - pt.x / 2, y, str, strlen(str));
}

- (void)drawRect:(CGRect)rect{

    CGContextRef theContext = UIGraphicsGetCurrentContext();
    CGRect viewBounds = self.bounds;

    CGContextTranslateCTM(theContext, 0, viewBounds.size.height);
    CGContextScaleCTM(theContext, 1, -1);

    CGContextSelectFont (theContext, "Helvetica", viewBounds.size.height,  kCGEncodingMacRoman);

    CGContextSetRGBFillColor (theContext, 1, 1, 1, 1);
    CGContextSetRGBStrokeColor (theContext, 0, 0, 0, 1);
    CGContextSetLineWidth(theContext, 1.0);

    ShowStringCentered(theContext, rect.size.width / 2.0, 12, [[self text] cStringUsingEncoding:NSASCIIStringEncoding]);
}

I just have a nagging feeling that I'm overlooking a simpler way to do this. Perhaps by overriding "drawTextInRect", but I can't seem to get drawTextInRect to bend to my will at all despite staring at it intently and frowning really really hard.

Body:
If your goal is something like this:

Here is how I achieved it: I added a new label of a custom class as a Subview to my current UILabel (inspired by this answer).

Just copy & paste it into your project and you are good to go:

extension UILabel {
    func addTextOutline(usingColor outlineColor: UIColor, outlineWidth: CGFloat) {
        class OutlinedText: UILabel{
            var outlineWidth: CGFloat = 0
            var outlineColor: UIColor = .clear

            override public func drawText(in rect: CGRect) {
                let shadowOffset = self.shadowOffset
                let textColor = self.textColor

                let c = UIGraphicsGetCurrentContext()
                c?.setLineWidth(outlineWidth)
                c?.setLineJoin(.round)
                c?.setTextDrawingMode(.stroke)
                self.textAlignment = .center
                self.textColor = outlineColor
                super.drawText(in:rect)

                c?.setTextDrawingMode(.fill)
                self.textColor = textColor
                self.shadowOffset = CGSize(width: 0, height: 0)
                super.drawText(in:rect)

                self.shadowOffset = shadowOffset
            }
        }

        let textOutline = OutlinedText()
        let outlineTag = 9999

        if let prevTextOutline = viewWithTag(outlineTag) {
            prevTextOutline.removeFromSuperview()
        }

        textOutline.outlineColor = outlineColor
        textOutline.outlineWidth = outlineWidth
        textOutline.textColor = textColor
        textOutline.font = font
        textOutline.text = text
        textOutline.tag = outlineTag

        sizeToFit()
        addSubview(textOutline)
        textOutline.frame = CGRect(x: -(outlineWidth / 2), y: -(outlineWidth / 2),
                                   width: bounds.width + outlineWidth,
                                   height: bounds.height + outlineWidth)
    }
}

USAGE:

yourLabel.addTextOutline(usingColor: .red, outlineWidth: 6)

it also works for a UIButton with all its animations:

yourButton.titleLabel?.addTextOutline(usingColor: .red, outlineWidth: 6)


问:
Spring/Thymeleaf throws "Cannot create a session after the response has been committed" when processing @PostMapping
I build a Spring MVC application with thymeleaf views and ran into the following problem. I have a page which should process a form and create a new Entity to persist in the database. In my controller class I have two methods for this. First, the @GetMapping to render the page:

```<code>@GetMapping("/dispo/orderCreate")
private String showCreateOrder(Model model) {
    List<MdUser> userList = service.getUsers();
    model.addAttribute("userList", userList);

    return "/dispo/orderCreate";
}
</code>```

As far as I just wanted to show the page without adding some action to the form, everything works fine. The model attribute "userList" is correctly populated with users from the database.

Now I changed the view to add an action and an object to the form. The code of the view now looks like this:

```<code><form action="#" class="form" id="newOrderForm" th:action="@{/dispo/addOrder}" th:object="${loadOrder}" method="post">
<table class="cont-table" cellpadding="2" cellspacing="2" width="100%">
    <tbody>
        <tr align="left">
            <th align="left" valign="top" width="110">Protokollführer:</th>
                <td>
                    <table border="0" cellpadding="0" cellspacing="1" width="100%">
                        <tbody>
                            <tr>
                                <td height="30">
                                    <select class="selectOneMenue" id="newOrderPersoDropDown" th:field="*{supervisor}">
                                        <option>Bitte auswählen</option>
                                        <option th:each="user : ${userList}"
                                                th:value="user.userId"
                                                th:text="${user.firstName}+' '+${user.lastName}"></option>
                                    </select>
                                </td>
                                    . . .
            </tr>
        </tbody>
    </table>
    <br />
    <input style="width:200px" type="submit" value="Speichern" class="commandExButton" id="newOrderSubmit" />
    <input style="width:120px" type="reset" value="Zurücksetzen" class="commandExButton" id="newOrderReset" />
</form>
</code>```

The corresponding @PostMapping looks like this:

```<code>@PostMapping("/dispo/addOrder")
public String submit(@ModelAttribute("loadOrder") LoadOrderModel loadOrder, BindingResult result, Model model) {
    if (result.hasErrors()) {
        return "error";
    }

    service.createAndSaveLoadOrder(loadOrder);
    return "/dispo/success";
}
</code>```

Now the rendering of the view crashes when the form is reached with the following stacktrace:

```<code>Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringActionTagProcessor' (template: "/dispo/orderCreate" - line 41, col 58)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleOpenElementEnd(TemplateHandlerAdapterMarkupHandler.java:304) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:278) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleOpenElementEnd(OutputExpressionInlinePreProcessorHandler.java:186) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:124) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.attoparser.HtmlElement.handleOpenElementEnd(HtmlElement.java:109) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.HtmlMarkupHandler.handleOpenElementEnd(HtmlMarkupHandler.java:297) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupEventProcessorHandler.handleOpenElementEnd(MarkupEventProcessorHandler.java:402) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.ParsingElementMarkupUtil.parseOpenElement(ParsingElementMarkupUtil.java:159) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:710) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
... 87 common frames omitted
Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:3030) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.connector.Request.getSession(Request.java:2468) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:896) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:908) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.saveToken(HttpSessionCsrfTokenRepository.java:63) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.csrf.LazyCsrfTokenRepository$SaveOnAccessCsrfToken.saveTokenIfNecessary(LazyCsrfTokenRepository.java:175) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.csrf.LazyCsrfTokenRepository$SaveOnAccessCsrfToken.getToken(LazyCsrfTokenRepository.java:127) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor.getExtraHiddenFields(CsrfRequestDataValueProcessor.java:71) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestDataValueProcessor.getExtraHiddenFields(SpringWebMvcThymeleafRequestDataValueProcessor.java:80) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.requestdata.RequestDataValueProcessorUtils.getExtraHiddenFields(RequestDataValueProcessorUtils.java:79) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.processor.SpringActionTagProcessor.doProcess(SpringActionTagProcessor.java:118) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.standard.processor.AbstractStandardExpressionAttributeTagProcessor.doProcess(AbstractStandardExpressionAttributeTagProcessor.java:142) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
... 100 common frames omitted
</code>```

Line 41 as indicated by the TemplateProcessingException is the line with the form tag.
I have nearly no experience with frontend development so please have patience with me. I think I have to do some http session managing here but don't know what to do and how to do it. Can anyone help me?

答:
I was also having the same issue; applied the suggestion by @Raistlin and its working fine now!!

I had a modal dialog with "form-post" in the lading page. It will fail if I try the modal first. And works fine if I try a GET page first, and come back to this page; definitely something to do with session.

always – a session will always be created if one doesn't already exist

ifRequired – a session will be created only if required (default)

never – the framework will never create a session itself but it will use one if it already exists

stateless – no session will be created or used by Spring Security

https://www.baeldung.com/spring-security-session

Body:
I build a Spring MVC application with thymeleaf views and ran into the following problem. I have a page which should process a form and create a new Entity to persist in the database. In my controller class I have two methods for this. First, the @GetMapping to render the page:

@GetMapping("/dispo/orderCreate")
private String showCreateOrder(Model model) {
    List<MdUser> userList = service.getUsers();
    model.addAttribute("userList", userList);

    return "/dispo/orderCreate";
}

As far as I just wanted to show the page without adding some action to the form, everything works fine. The model attribute "userList" is correctly populated with users from the database.

Now I changed the view to add an action and an object to the form. The code of the view now looks like this:

<form action="#" class="form" id="newOrderForm" th:action="@{/dispo/addOrder}" th:object="${loadOrder}" method="post">

            Protokollführer:

                                    <select class="selectOneMenue" id="newOrderPersoDropDown" th:field="*{supervisor}">
                                        <option>Bitte auswählen</option>
                                        <option th:each="user : ${userList}"
                                                th:value="user.userId"
                                                th:text="${user.firstName}+' '+${user.lastName}"></option>
                                    </select>

                                    . . .

    <input style="width:200px" type="submit" value="Speichern" class="commandExButton" id="newOrderSubmit" />
    <input style="width:120px" type="reset" value="Zurücksetzen" class="commandExButton" id="newOrderReset" />
</form>

The corresponding @PostMapping looks like this:

@PostMapping("/dispo/addOrder")
public String submit(@ModelAttribute("loadOrder") LoadOrderModel loadOrder, BindingResult result, Model model) {
    if (result.hasErrors()) {
        return "error";
    }

    service.createAndSaveLoadOrder(loadOrder);
    return "/dispo/success";
}

Now the rendering of the view crashes when the form is reached with the following stacktrace:

Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringActionTagProcessor' (template: "/dispo/orderCreate" - line 41, col 58)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleOpenElementEnd(TemplateHandlerAdapterMarkupHandler.java:304) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:278) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleOpenElementEnd(OutputExpressionInlinePreProcessorHandler.java:186) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:124) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.attoparser.HtmlElement.handleOpenElementEnd(HtmlElement.java:109) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.HtmlMarkupHandler.handleOpenElementEnd(HtmlMarkupHandler.java:297) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupEventProcessorHandler.handleOpenElementEnd(MarkupEventProcessorHandler.java:402) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.ParsingElementMarkupUtil.parseOpenElement(ParsingElementMarkupUtil.java:159) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:710) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]
... 87 common frames omitted
Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:3030) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.connector.Request.getSession(Request.java:2468) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:896) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:908) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.saveToken(HttpSessionCsrfTokenRepository.java:63) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.csrf.LazyCsrfTokenRepository$SaveOnAccessCsrfToken.saveTokenIfNecessary(LazyCsrfTokenRepository.java:175) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.csrf.LazyCsrfTokenRepository$SaveOnAccessCsrfToken.getToken(LazyCsrfTokenRepository.java:127) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor.getExtraHiddenFields(CsrfRequestDataValueProcessor.java:71) ~[spring-security-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestDataValueProcessor.getExtraHiddenFields(SpringWebMvcThymeleafRequestDataValueProcessor.java:80) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.requestdata.RequestDataValueProcessorUtils.getExtraHiddenFields(RequestDataValueProcessorUtils.java:79) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.spring5.processor.SpringActionTagProcessor.doProcess(SpringActionTagProcessor.java:118) ~[thymeleaf-spring5-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.standard.processor.AbstractStandardExpressionAttributeTagProcessor.doProcess(AbstractStandardExpressionAttributeTagProcessor.java:142) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE]
... 100 common frames omitted

Line 41 as indicated by the TemplateProcessingException is the line with the form tag.
I have nearly no experience with frontend development so please have patience with me. I think I have to do some http session managing here but don't know what to do and how to do it. Can anyone help me?


问:
Fetch nested data from MongoDB
I have a collection in the following format.

```<code>{
    "_id": "ffffc446-f33d",
    "className": "com.ezdx.vist.model.Visit",
    "organizationId": "0a0beff7-fe1e-4ab7",
    "centerId": "9aef68fe-dffd-4a7d-b0ee-f8dd3fc03303",
    "tests": [{
            "result": 157,
            "type": "PHYSICAL",
            **"name": "HEIGHT",**
            "consumableQuantity": 0,
            "testCost": 0,
            "testExpenseConsumable": 0

        },
        {
            "result": 8,
            "type": "RDT",
            **"name": "URIC",**
            "consumableQuantity": 0,
            "testCost": 0,
            "testExpenseConsumable": 0
        }

    ],
    "repeatVisit": true
}
</code>```

I want the collection where test.name = "Uric" and with particular columns.

```<code>  {
    "result": 8,
    "type": "RDT",
    **"name": "Uric",**
    "consumableQuantity": 0,
    "testCost": 0,
    "testExpenseConsumable": 0
}
</code>```

Somehow I manage to the desired collections but I am not able to get the desired format.
Below is my query

```<code>db.visits.aggregate( [ { $unwind : "$tests" },
{ $match: { $and: [{"tests.name":"URIC"}]
    } } ] )
</code>```

答:
As an alternative to the Valijon's answer, you can use $filter aggregation which may be faster because we didn't applied $unwind.

db.collection.aggregate([
  {
    $project: {
      items: {
        $filter: {
          input: "$tests",
          as: "item",
          cond: {
            $eq: [
              "$$item.name",
              "URIC"
            ]
          }
        }
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: {
        $arrayElemAt: [
          "$items",
          0
        ]
      }
    }
  }
])
```

Playground

Title: Fetch nested data from MongoDB

Body:
I have a collection in the following format.

{
    "_id": "ffffc446-f33d",
    "className": "com.ezdx.vist.model.Visit",
    "organizationId": "0a0beff7-fe1e-4ab7",
    "centerId": "9aef68fe-dffd-4a7d-b0ee-f8dd3fc03303",
    "tests": [{
            "result": 157,
            "type": "PHYSICAL",
            **"name": "HEIGHT",**
            "consumableQuantity": 0,
            "testCost": 0,
            "testExpenseConsumable": 0

        },
        {
            "result": 8,
            "type": "RDT",
            **"name": "URIC",**
            "consumableQuantity": 0,
            "testCost": 0,
            "testExpenseConsumable": 0
        }

    ],
    "repeatVisit": true
}

I want the collection where test.name = "Uric" and with particular columns.

  {
    "result": 8,
    "type": "RDT",
    **"name": "Uric",**
    "consumableQuantity": 0,
    "testCost": 0,
    "testExpenseConsumable": 0
}

Somehow I manage to the desired collections but I am not able to get the desired format.
Below is my query

db.visits.aggregate( [ { $unwind : "$tests" },
{ $match: { $and: [{"tests.name":"URIC"}]
    } } ] )

Body:
As an alternative to the Valijon's answer, you can use $filter aggregation which may be faster because we didn't applied $unwind.

db.collection.aggregate([
  {
    $project: {
      items: {
        $filter: {
          input: "$tests",
          as: "item",
          cond: {
            $eq: [
              "$$item.name",
              "URIC"
            ]
          }
        }
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: {
        $arrayElemAt: [
          "$items",
          0
        ]
      }
    }
  }
])

Playground


问:
Is there any dropdown available with filter feature in angular material? NB: Using mat-select not mat-option
I have searched for a filtered dropdown option in angular material and could not find anything with mat-select multiselect.
I don't think an implementation is available in angular material for mat-select.
Is there a way to implement this using angular material?</p>

答:
Well, We can create a material input form control that was a multiselect with filter.

As the answer is a bit larger, you can see the result in the stackblitz

The idea is that we has a component that has a @input that can be an array of strings or an array of object. We has three auxiliars variables

```<code>  _list: any[]; //<--an array of object
  keys: string[]; //an array with two values, the "key" and the "text"
  listFiltered: any[]; //<--the list above filtered
</code>```

And two formControls, one to show the value and one to filter the list

```<code>  control = new FormControl();
  search = new FormControl();
</code>```

When we received the list in a input we create the _list and give value to keys

```<code>  @Input() set list(value) {
    this._list =
      typeof value[0] == "string"
        ? value.map(x => ({ key: x, value: x }))
        : [...value];
    this.keys = Object.keys(this._list[0]);
</code>```

So, e.g.

```<code>list: any[] = [
    {id:1,name:"Extra cheese"},
    {id:2,name:"Mushroom"},
    {id:3,name:"Onion"},
    {id:4,name:"Pepperoni"},
    {id:5,name:"Sausage"},
    {id:6,name:"Tomato"}
  ];
_list=[...list]
keys[0]="id"; keys[1]="name"
</code>```

if

```<code>list=["Extra cheese","Mushroom","Onion","Pepperoni",name:"Sausage","Tomato"}
_list will be
        {key:"Extra cheese",value:"Extra cheese"},
        {key:"Mushroom",value:"Mushroom"},
        {key:"Onion",value:"Onion"},
        {key:"Pepperoni",value:"Pepperoni"},
        {key:"Sausage",value:"Sausage"},
        {key:"Tomato",value:"Tomato"}
 and
    keys[0]="key"; keys[1]="value"
</code>```

This allow us create a component that has a formControl and a "menu"

```<code><div class="multi-select">
      <input (click)="trigger.openMenu()" readonly [formControl]="control" />
      <span #menu class="mat-select-wrapper" [matMenuTriggerFor]="appMenu" (menuOpened)="searchID.focus()">
        <span class="mat-select-arrow"> </span>
      </span>
    </div>
    <mat-menu #appMenu="matMenu" xPosition="before">
      <div class="menu" (click)="$event.stopPropagation()">
        <mat-form-field>
          <mat-label>Search</mat-label>
          <input #searchID matInput placeholder="search" [formControl]="search" />
        </mat-form-field>
        <div class="mat-menu-item" *ngFor="let item of listFiltered">
          <mat-checkbox
            [checked]="item.checked"
            (change)="change($event.checked, item[keys[0]])"
          >
            {{ item[keys[1]] }}</mat-checkbox
          >
        </div>
      </div>
    </mat-menu>
</code>```

We need use a ViewChild to open the menu when the control is focused

```<code>@ViewChild(MatMenuTrigger, { static: false }) trigger: MatMenuTrigger;
</code>```

If we use in ngOnInit

```<code>    this.search.valueChanges
      .pipe(
        startWith(null),
        delay(200)
      )
      .subscribe(res => {
        const search = res ? res.toLowerCase() : "";
        this.listFiltered = this._list.filter(
          x => !res || x.checked ||
                x[this.keys[1]].toLowerCase().indexOf(search) >= 0
        );
      });
  }
</code>```

An a function (change)

```<code>change(value, key) {
    const item = this._list.find(x => x[this.keys[0]] == key);
    item.checked = value;
  }
</code>```

when we change the search, the listFiltered contains the elements of the control and the elements that containst the value, and this._list will be an array with elements that has a property "checked" that becomes true if selected.

Well, Now the difficult part is convert to a mat custom form control. We need follow the guide in the docs

In brief, we need add a provider and host some classes

```<code>  providers: [
    { provide: MatFormFieldControl, useExisting: MultiSelectFilterComponent }
  ],
  host: {
    "[class.example-floating]": "shouldLabelFloat",
    "[id]": "id",
    "[attr.aria-describedby]": "describedBy"
  }
</code>```

In constructor inject FocusMonitor,ElementRef and ngControl

```<code>  control = new FormControl();
  search = new FormControl();
</code>```0

Add somes variables and Inputs

```<code>  control = new FormControl();
  search = new FormControl();
</code>```1

And the methods

```<code>  control = new FormControl();
  search = new FormControl();
</code>```2

Body:
Well, We can create a material input form control that was a multiselect with filter.

As the answer is a bit larger, you can see the result in the stackblitz

The idea is that we has a component that has a @input that can be an array of strings or an array of object. We has three auxiliars variables

  _list: any[]; //<--an array of object
  keys: string[]; //an array with two values, the "key" and the "text"
  listFiltered: any[]; //<--the list above filtered

And two formControls, one to show the value and one to filter the list

  control = new FormControl();
  search = new FormControl();

When we received the list in a input we create the _list and give value to keys

  @Input() set list(value) {
    this._list =
      typeof value[0] == "string"
        ? value.map(x => ({ key: x, value: x }))
        : [...value];
    this.keys = Object.keys(this._list[0]);

So, e.g.

list: any[] = [
    {id:1,name:"Extra cheese"},
    {id:2,name:"Mushroom"},
    {id:3,name:"Onion"},
    {id:4,name:"Pepperoni"},
    {id:5,name:"Sausage"},
    {id:6,name:"Tomato"}
  ];
_list=[...list]
keys[0]="id"; keys[1]="name"

if

list=["Extra cheese","Mushroom","Onion","Pepperoni",name:"Sausage","Tomato"}
_list will be
        {key:"Extra cheese",value:"Extra cheese"},
        {key:"Mushroom",value:"Mushroom"},
        {key:"Onion",value:"Onion"},
        {key:"Pepperoni",value:"Pepperoni"},
        {key:"Sausage",value:"Sausage"},
        {key:"Tomato",value:"Tomato"}
 and
    keys[0]="key"; keys[1]="value"

This allow us create a component that has a formControl and a "menu"

<div class="multi-select">
      <input (click)="trigger.openMenu()" readonly [formControl]="control" />
      <span #menu class="mat-select-wrapper" [matMenuTriggerFor]="appMenu" (menuOpened)="searchID.focus()">
        <span class="mat-select-arrow"> </span>
      </span>
    </div>
    <mat-menu #appMenu="matMenu" xPosition="before">
      <div class="menu" (click)="$event.stopPropagation()">
        <mat-form-field>
          <mat-label>Search</mat-label>
          <input #searchID matInput placeholder="search" [formControl]="search" />
        </mat-form-field>
        <div class="mat-menu-item" *ngFor="let item of listFiltered">
          <mat-checkbox
            [checked]="item.checked"
            (change)="change($event.checked, item[keys[0]])"
          >
            {{ item[keys[1]] }}</mat-checkbox
          >
        </div>
      </div>
    </mat-menu>

We need use a ViewChild to open the menu when the control is focused

@ViewChild(MatMenuTrigger, { static: false }) trigger: MatMenuTrigger;

If we use in ngOnInit

    this.search.valueChanges
      .pipe(
        startWith(null),
        delay(200)
      )
      .subscribe(res => {
        const search = res ? res.toLowerCase() : "";
        this.listFiltered = this._list.filter(
          x => !res || x.checked ||
                x[this.keys[1]].toLowerCase().indexOf(search) >= 0
        );
      });
  }

An a function (change)

change(value, key) {
    const item = this._list.find(x => x[this.keys[0]] == key);
    item.checked = value;
  }

when we change the search, the listFiltered contains the elements of the control and the elements that containst the value, and this._list will be an array with elements that has a property "checked" that becomes true if selected.

Well, Now the difficult part is convert to a mat custom form control. We need follow the guide in the docs

In brief, we need add a provider and host some classes

  providers: [
    { provide: MatFormFieldControl, useExisting: MultiSelectFilterComponent }
  ],
  host: {
    "[class.example-floating]": "shouldLabelFloat",
    "[id]": "id",
    "[attr.aria-describedby]": "describedBy"
  }

In constructor inject FocusMonitor,ElementRef and ngControl

  constructor(
    private _focusMonitor: FocusMonitor,
    private _elementRef: ElementRef<HTMLElement>,
    @Optional() @Self() public ngControl: NgControl
  ) {
    _focusMonitor.monitor(_elementRef, true).subscribe(origin => {
      if (this.focused && !origin) {
        this.onTouched();
      }
      this.focused = !!origin;
      this.stateChanges.next();
    });

    if (this.ngControl != null) {
      this.ngControl.valueAccessor = this;
    }
  }

Add somes variables and Inputs

  controlType = "multi-select-filter";
  static nextId = 0;
  static ngAcceptInputType_disabled: boolean | string | null | undefined;
  id = `multi-select-filter-${MultiSelectFilterComponent.nextId++}`;
  describedBy = "";
  onChange = (_: any) => {};
  onTouched = () => {};

  stateChanges = new Subject<void>();
  focused = false;
  get errorState() //<----This is IMPORTANT, give us if the control is valid or nor
  {
      return this.ngControl?this.ngControl.invalid && this.ngControl.touched:false;
  }
  get empty() {
    return !this.control.value;
  }
  get shouldLabelFloat() {
    return this.focused || !this.empty;
  }
  @Input()
  get placeholder(): string {
    return this._placeholder;
  }
  set placeholder(value: string) {
    this._placeholder = value;
    this.stateChanges.next();
  }
  private _placeholder: string;

  @Input()
  get required(): boolean {
    return this._required;
  }
  set required(value: boolean) {
    this._required = coerceBooleanProperty(value);
    this.stateChanges.next();
  }
  private _required = false;

  @Input()
  get disabled(): boolean {
    return this._disabled;
  }
  set disabled(value: boolean) {
    this._disabled = coerceBooleanProperty(value);
    this._disabled ? this.control.disable() : this.control.enable();
    this.stateChanges.next();
  }
  private _disabled = false;

  @Input()
  get value(): any[] | null {  //<--this is the value of our control
    if (!this._list) return null; //In my case we return an array based in
                                  //this._list
    const result = this._list.filter((x: any) => x.checked);
    return result && result.length > 0
      ? result.filter(x => x.checked).map(x => x[this.keys[0]])
      : null;
  }
  set value(value: any[] | null) {
    if (this._list && value) {
      this._list.forEach(x => {
        x.checked = value.indexOf(x[this.keys[0]]) >= 0;
      })
        const result = this._list.filter((x: any) => x.checked);
        this.control.setValue(
          result.map((x: any) => x[this.keys[1]]).join(",")
        );
        this.onChange(result.map((x: any) => x[this.keys[0]]));
    } else
    {
      this.onChange(null);
        this.control.setValue(null);
    }
    this.stateChanges.next();
  }

And the methods

  ngOnDestroy() {
    this.stateChanges.complete();
    this._focusMonitor.stopMonitoring(this._elementRef);
  }

  setDescribedByIds(ids: string[]) {
    this.describedBy = ids.join(" ");
  }

  onContainerClick(event: MouseEvent) {
    if ((event.target as Element).tagName.toLowerCase() != "input") {
      this._elementRef.nativeElement.querySelector("input")!.focus();
    }
  }
  writeValue(value: any[] | null): void {
    this._value = value;
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }


问:
Retrieve user details after providing the primary key in Django Rest Framework
ImproperlyConfigured at /api/account/profile/36 Could not resolve URL for hyperlinked relationship using view name "account-detail". You may have failed to include the related model in your API, or incorrectly configured the lookup_field attribute on this field.

views.py

```<code>@api_view(['GET', ])
def retrieve_user_account_view(self, pk):
    user_account = query_db(pk)
    factory = APIRequestFactory()
    request = factory.get('/')
    serializer = AccountSerializer(instance=user_account, context={'request':
        Request(request)})
    return JsonResponse(serializer.data)
</code>```

serializers.py

```<code>class AccountSerializer(serializers.HyperlinkedModelSerializer):
    confirm_password = serializers.CharField(style={'input_type': 'password'}, write_only=True)

    class Meta:
        model = Account
        fields = ('url', 'id', 'full_name', 'email', 'password',
                  'confirm_password',
                  'date_created', 'last_updated', 'phone_number', 'status')
        extra_kwargs = {
                  'password': {'write_only': True}
        }
</code>```

models.py

```<code>class Account(models.Model):
    full_name = models.CharField(max_length=255)
    email = models.EmailField(unique=True)
    password = models.CharField(max_length=255)
    date_created = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=12, auto_created=True,
        default='ACTIVE')
    phone_number = PhoneNumberField(region='NG')

    class Meta:
        ordering = ['date_created']
</code>```

urls.py

```<code>from account.api.views import(
    user_account_registration_view,
    retrieve_user_account_view,
    update_user_account_view,
    delete_user_account_view,
)

app_name = "account"

urlpatterns = [
    path('register', user_account_registration_view, name="register"),
    path('profile/<int:pk>', retrieve_user_account_view, name="retrieve"),
    path('profile/update/<int:pk>', update_user_account_view, name="update"),
    path('profile/delete/<int:pk>', delete_user_account_view, name="delete"),
]
</code>```

答:
I think you should change the second path from

```<code>path('profile/<int:pk>', retrieve_user_account_view, name="retrieve"),
</code>```

to

```<code>path('profile/<int:pk>', retrieve_user_account_view, name="account-detail"),
</code>```

Or just pass the view_name via extra_args in your HyperlinkedModelSerializer

How hyperlinked views are determined

Body:
ImproperlyConfigured at /api/account/profile/36 Could not resolve URL for hyperlinked relationship using view name "account-detail". You may have failed to include the related model in your API, or incorrectly configured the lookup_field attribute on this field.

views.py

@api_view(['GET', ])
def retrieve_user_account_view(self, pk):
    user_account = query_db(pk)
    factory = APIRequestFactory()
    request = factory.get('/')
    serializer = AccountSerializer(instance=user_account, context={'request':
        Request(request)})
    return JsonResponse(serializer.data)

serializers.py

class AccountSerializer(serializers.HyperlinkedModelSerializer):
    confirm_password = serializers.CharField(style={'input_type': 'password'}, write_only=True)

    class Meta:
        model = Account
        fields = ('url', 'id', 'full_name', 'email', 'password',
                  'confirm_password',
                  'date_created', 'last_updated', 'phone_number', 'status')
        extra_kwargs = {
                  'password': {'write_only': True}
        }

models.py

class Account(models.Model):
    full_name = models.CharField(max_length=255)
    email = models.EmailField(unique=True)
    password = models.CharField(max_length=255)
    date_created = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=12, auto_created=True,
        default='ACTIVE')
    phone_number = PhoneNumberField(region='NG')

    class Meta:
        ordering = ['date_created']

urls.py

from account.api.views import(
    user_account_registration_view,
    retrieve_user_account_view,
    update_user_account_view,
    delete_user_account_view,
)

app_name = "account"

urlpatterns = [
    path('register', user_account_registration_view, name="register"),
    path('profile/<int:pk>', retrieve_user_account_view, name="retrieve"),
    path('profile/update/<int:pk>', update_user_account_view, name="update"),
    path('profile/delete/<int:pk>', delete_user_account_view, name="delete"),
]

Body:
I think you should change the second path from

path('profile/<int:pk>', retrieve_user_account_view, name="retrieve"),

to

path('profile/<int:pk>', retrieve_user_account_view, name="account-detail"),

Or just pass the view_name via extra_args in your HyperlinkedModelSerializer

How hyperlinked views are determined


问:
useState doesn't update the value, and the value keep remains null
I'm building my website with React, and I'm using useState to get the id of hovered item.

But when I use setState to get the value, it doesn't update and remain 'null'

So on console, I can see the event.target.id is recognized, but even after the setState event, the state value return null.

Can anybody give some clues on what is happening here?

Here's the code

```<code>import React from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import styled from 'styled-components'

const WorksTitle = props => {
  const { type, title, imgSrc, link, year } = props
  const [currentMenu, setCurrentMenu] = React.useState(null)

  const handleHover = event => {
    console.log(
      'event target: ',
      event.target,
      ' / ',
      'event target id: ',
      event.target.id
    )
    **console.log(event.target.id)
    setCurrentMenu(event.target.id)
    console.log(currentMenu)**
  }

  const handleMouseOut = event => {
    console.log('mouse out from:', event.target.id)
    setCurrentMenu(null)
  }

  return (
    <StyledWorksTitle>
      <TitleItem id={title} onMouseOverCapture={handleHover} onMouseOut={handleMouseOut}>
        <div className={`itemWrapper ${(currentMenu === { title } ||
            currentMenu === null) && 'activated'}`}
          id={title}>
          <Link to={link}></Link>
        </div>
      </TitleItem>
    </StyledWorksTitle>
  )
}

/* styled-components */

export default WorksTitle

</code>```

答:
setState is an async call which means the console.log immediately after it wont have the updated value. For debugging purposes do this:
right after StyledWorksTitle create a button and write in it like this:

```<code>   <button onClick={()=>console.log(currentMenu)}></button>
</code>```

You should be able to see your updated value now.

As to how to handle its implementation. I would recommend using useEffect() and passing the currentMenu state as its dependency.

```<code>   useEffect(()=>{
    //write a function to push hovered item id into an array or something
   },currentMenu)
</code>```

This is very generic because i dont know what you want to do with the ID but in anycase this will help you in your path.

Body:
I'm building my website with React, and I'm using useState to get the id of hovered item.

But when I use setState to get the value, it doesn't update and remain 'null'

So on console, I can see the event.target.id is recognized, but even after the setState event, the state value return null.

Can anybody give some clues on what is happening here?

Here's the code

import React from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import styled from 'styled-components'

const WorksTitle = props => {
  const { type, title, imgSrc, link, year } = props
  const [currentMenu, setCurrentMenu] = React.useState(null)

  const handleHover = event => {
    console.log(
      'event target: ',
      event.target,
      ' / ',
      'event target id: ',
      event.target.id
    )
    **console.log(event.target.id)
    setCurrentMenu(event.target.id)
    console.log(currentMenu)**
  }

  const handleMouseOut = event => {
    console.log('mouse out from:', event.target.id)
    setCurrentMenu(null)
  }

  return (

  )
}

/* styled-components */

export default WorksTitle

Body:
setState is an async call which means the console.log immediately after it wont have the updated value. For debugging purposes do this:
right after StyledWorksTitle create a button and write in it like this:

   <button onClick={()=>console.log(currentMenu)}></button>

You should be able to see your updated value now.

As to how to handle its implementation. I would recommend using useEffect() and passing the currentMenu state as its dependency.

   useEffect(()=>{
    //write a function to push hovered item id into an array or something
   },currentMenu)

This is very generic because i dont know what you want to do with the ID but in anycase this will help you in your path.


问:
Failed put request to solr
I have new a json file, and I want overwrite the feature-store json file on solr with my new json file. So I write the following code:

```<code>filename ='_schema_feature-store.json'

import requests
import json
from requests.auth import HTTPBasicAuth

with open(filename) as json_f:
    solrModel = json.load(json_f)
    url = 'http://xx.xxx.xx.xx:xxxx/solr/someurl/' + "schema/feature-store"
    resp = requests.put(url, json.dumps(solrModel), auth=HTTPBasicAuth('username', 'password'))
    print(resp.text)
</code>```

Of course the url above is a real url.

But on sending this request, I get the following response:

```<code>{
  "responseHeader":{
    "status":500,
    "QTime":1174},
  "error":{
    "msg":"ts_title_0 already contained in the store, please use a different name",
    "trace":"org.apache.solr.ltr.feature.FeatureException: ts_title_0 already contained in the store, please use a different name\n\tat org.apache.solr.ltr.store.FeatureStore.add(FeatureStore.java:50)\n\tat org.apache.solr.ltr.store.res\
t.ManagedFeatureStore.addFeature(ManagedFeatureStore.java:122)\n\tat org.apache.solr.ltr.store.rest.ManagedFeatureStore.applyUpdatesToManagedData(ManagedFeatureStore.java:132)\n\tat org.apache.solr.rest.ManagedResource.doPut(ManagedReso\
urce.java:395)\n\tat org.apache.solr.rest.RestManager$ManagedEndpoint.put(RestManager.java:340)\n\tat org.restlet.resource.ServerResource.doHandle(ServerResource.java:447)\n\tat org.restlet.resource.ServerResource.doConditionalHandle(Se\
rverResource.java:359)\n\tat org.restlet.resource.ServerResource.handle(ServerResource.java:1044)\n\tat org.restlet.resource.Finder.handle(Finder.java:236)\n\tat org.restlet.routing.Filter.doHandle(Filter.java:150)\n\tat org.restlet.rou\
ting.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Router.doHandle(Router.java:422)\n\tat org.restlet.routing.Router.handle(Router.java:639)\n\tat org.restlet.routing.Filter.doHandle(Filter.java:150)\n\tat org.restlet.routing\
.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Filter.doHandle(Filter.java:150)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Filter.doHandle(Filter.java:150)\n\tat org.restlet.engine.appl\
ication.StatusFilter.doHandle(StatusFilter.java:140)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Filter.doHandle(Filter.java:150)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.\
restlet.engine.CompositeHelper.handle(CompositeHelper.java:202)\n\tat org.restlet.engine.application.ApplicationHelper.handle(ApplicationHelper.java:75)\n\tat org.restlet.Application.handle(Application.java:385)\n\tat org.restlet.routin\
g.Filter.doHandle(Filter.java:150)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Router.doHandle(Router.java:422)\n\tat org.restlet.routing.Router.handle(Router.java:639)\n\tat org.restlet.routing.Fi\
lter.doHandle(Filter.java:150)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Router.doHandle(Router.java:422)\n\tat org.restlet.routing.Router.handle(Router.java:639)\n\tat org.restlet.routing.Filter\
.doHandle(Filter.java:150)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:202)\n\tat org.restlet.Component.handle(Component.java:408)\n\tat org.restlet.Serve\
r.handle(Server.java:507)\n\tat org.restlet.engine.connector.ServerHelper.handle(ServerHelper.java:63)\n\tat org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:143)\n\tat org.restlet.ext.servlet.ServerServlet.servi\
ce(ServerServlet.java:1117)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:790)\n\tat org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845)\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletH\
andler.java:584)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)\n\tat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:566)\n\tat org.eclipse.jetty.server.session.SessionHandler\
.doHandle(SessionHandler.java:226)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)\n\tat org.eclipse.jetty.server.s\
ession.SessionHandler.doScope(SessionHandler.java:185)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\n\tat org\
.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:199)\n\tat org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:74)\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:356)\n\tat org.apache.\
solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:298)\n\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1691)\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.j\
ava:582)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)\n\tat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)\n\tat org.eclipse.jetty.server.session.SessionHandler.doHandl\
e(SessionHandler.java:226)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)\n\tat org.eclipse.jetty.server.session.S\
essionHandler.doScope(SessionHandler.java:185)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\n\tat org.eclipse\
.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)\n\tat org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.h\
andle(HandlerWrapper.java:134)\n\tat org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:335)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)\n\tat org.eclipse.jetty.server.S\
erver.handle(Server.java:534)\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)\n\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCa\
llback.succeeded(AbstractConnection.java:273)\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)\n\tat org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)\n\tat org.eclipse.jetty.util.thre\
ad.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)\n\tat org.eclipse.jetty.util.threa\
d.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java\
:589)\n\tat java.lang.Thread.run(Thread.java:748)\n",  ...

</code>```

and so on. I think the most noteworthy part of the error is:

```<code>ts_title_0 already contained in the store
</code>```

However, my new json file contains only one ts_title_0 as follows:

```<code>"name":"ts_title_0",
</code>```

and that's the only instance of ts_title_0 in the whole file. Then why this error?

答:
i believe you should use the update url with requests.post. For example:

```<code>url='http://localhost:8983/solr/my_collection/update?commit=true'
payload=open(filename, 'rb').read()
headers={'Content-type':'application/csv'}
response = requests.post(url, auth=('user', 'passwd'), headers=headers, data=payload, timeout=5)`
</code>```

check out the solr load testing script where I am updating same csv file multiple times:
https://github.com/itzmestar/solr/blob/master/solr_post.py

hope this helps

Title: Failed put request to solr

Body:
I have new a json file, and I want overwrite the feature-store json file on solr with my new json file. So I write the following code:

filename ='_schema_feature-store.json'

import requests
import json
from requests.auth import HTTPBasicAuth

with open(filename) as json_f:
    solrModel = json.load(json_f)
    url = 'http://xx.xxx.xx.xx:xxxx/solr/someurl/' + "schema/feature-store"
    resp = requests.put(url, json.dumps(solrModel), auth=HTTPBasicAuth('username', 'password'))
    print(resp.text)

Of course the url above is a real url.

But on sending this request, I get the following response:

{
  "responseHeader":{
    "status":500,
    "QTime":1174},
  "error":{
    "msg":"ts_title_0 already contained in the store, please use a different name",
    "trace":"org.apache.solr.ltr.feature.FeatureException: ts_title_0 already contained in the store, please use a different name\n\tat org.apache.solr.ltr.store.FeatureStore.add(FeatureStore.java:50)\n\tat org.apache.solr.ltr.store.res\
t.ManagedFeatureStore.addFeature(ManagedFeatureStore.java:122)\n\tat org.apache.solr.ltr.store.rest.ManagedFeatureStore.applyUpdatesToManagedData(ManagedFeatureStore.java:132)\n\tat org.apache.solr.rest.ManagedResource.doPut(ManagedReso\
urce.java:395)\n\tat org.apache.solr.rest.RestManager$ManagedEndpoint.put(RestManager.java:340)\n\tat org.restlet.resource.ServerResource.doHandle(ServerResource.java:447)\n\tat org.restlet.resource.ServerResource.doConditionalHandle(Se\
rverResource.java:359)\n\tat org.restlet.resource.ServerResource.handle(ServerResource.java:1044)\n\tat org.restlet.resource.Finder.handle(Finder.java:236)\n\tat org.restlet.routing.Filter.doHandle(Filter.java:150)\n\tat org.restlet.rou\
ting.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Router.doHandle(Router.java:422)\n\tat org.restlet.routing.Router.handle(Router.java:639)\n\tat org.restlet.routing.Filter.doHandle(Filter.java:150)\n\tat org.restlet.routing\
.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Filter.doHandle(Filter.java:150)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Filter.doHandle(Filter.java:150)\n\tat org.restlet.engine.appl\
ication.StatusFilter.doHandle(StatusFilter.java:140)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Filter.doHandle(Filter.java:150)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.\
restlet.engine.CompositeHelper.handle(CompositeHelper.java:202)\n\tat org.restlet.engine.application.ApplicationHelper.handle(ApplicationHelper.java:75)\n\tat org.restlet.Application.handle(Application.java:385)\n\tat org.restlet.routin\
g.Filter.doHandle(Filter.java:150)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Router.doHandle(Router.java:422)\n\tat org.restlet.routing.Router.handle(Router.java:639)\n\tat org.restlet.routing.Fi\
lter.doHandle(Filter.java:150)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.restlet.routing.Router.doHandle(Router.java:422)\n\tat org.restlet.routing.Router.handle(Router.java:639)\n\tat org.restlet.routing.Filter\
.doHandle(Filter.java:150)\n\tat org.restlet.routing.Filter.handle(Filter.java:197)\n\tat org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:202)\n\tat org.restlet.Component.handle(Component.java:408)\n\tat org.restlet.Serve\
r.handle(Server.java:507)\n\tat org.restlet.engine.connector.ServerHelper.handle(ServerHelper.java:63)\n\tat org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:143)\n\tat org.restlet.ext.servlet.ServerServlet.servi\
ce(ServerServlet.java:1117)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:790)\n\tat org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845)\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletH\
andler.java:584)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)\n\tat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:566)\n\tat org.eclipse.jetty.server.session.SessionHandler\
.doHandle(SessionHandler.java:226)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)\n\tat org.eclipse.jetty.server.s\
ession.SessionHandler.doScope(SessionHandler.java:185)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\n\tat org\
.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:199)\n\tat org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:74)\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:356)\n\tat org.apache.\
solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:298)\n\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1691)\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.j\
ava:582)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)\n\tat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)\n\tat org.eclipse.jetty.server.session.SessionHandler.doHandl\
e(SessionHandler.java:226)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)\n\tat org.eclipse.jetty.server.session.S\
essionHandler.doScope(SessionHandler.java:185)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\n\tat org.eclipse\
.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)\n\tat org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.h\
andle(HandlerWrapper.java:134)\n\tat org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:335)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)\n\tat org.eclipse.jetty.server.S\
erver.handle(Server.java:534)\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)\n\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCa\
llback.succeeded(AbstractConnection.java:273)\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)\n\tat org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)\n\tat org.eclipse.jetty.util.thre\
ad.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)\n\tat org.eclipse.jetty.util.threa\
d.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java\
:589)\n\tat java.lang.Thread.run(Thread.java:748)\n",  ...

and so on. I think the most noteworthy part of the error is:

ts_title_0 already contained in the store

However, my new json file contains only one ts_title_0 as follows:

"name":"ts_title_0",

and that's the only instance of ts_title_0 in the whole file. Then why this error?

Body:
i believe you should use the update url with requests.post. For example:

url='http://localhost:8983/solr/my_collection/update?commit=true'
payload=open(filename, 'rb').read()
headers={'Content-type':'application/csv'}
response = requests.post(url, auth=('user', 'passwd'), headers=headers, data=payload, timeout=5)`

check out the solr load testing script where I am updating same csv file multiple times:
https://github.com/itzmestar/solr/blob/master/solr_post.py

hope this helps


问:
java - live view on collection contained within a collection contained within ... etc
I have a class A which can contain many instances of class B which may in turn contain many instances of Class C, which can contain many instances of class D

Now, in class A I have a method getAllD. Currently every time this is called there is a lot of iterating that takes place, and a rather large list is freshly created and returned. This cannot be very efficient.

I was wondering how I could do this better. This question Combine multiple Collections into a single logical Collection? seems to touch upon a similar topic, but I'm not really sure how I could apply it to my situation.

All comments are much appreciated!

答:
This cannot be very efficient.

Iterating in-memory is pretty damn fast. Also the efficiency of creating an ArrayList of 10 k elements compared to creating 10 ArrayList with 1k elements each won't be that drastically different. So, in conclusion, you should probably first just go with the most straight-forward iterating. Chances are that this works just fine.

Even if you have gazillion elements, it is probably wise to implement a straight-forward iterating anyways for comparison. Otherwise you don't know if you are being able to optimize or if you are slowing things down by doing things clever.

Having said that, if you want to optimize for sequential read access of all Ds, I'd maintain an "index" outside. The index could be a LinkedList, ArrayList, TreeList etc. depending on your situation. For example, if you aren't sure of the length of the index, it is probably wise to avoid ArrayList. If you want to efficiently remove random elements using the reference of that element, OrderedSet might be much better than a list etc.

When you do this you have to worry about the consistency of the index & actual references in your classes. I.e. more complexity = more place to hide bugs. So, unless you find it necessary through performance testing, it is really not advisable to attempt an optimization.

(btw avoiding instantiation of new collection objects are unlikely to make things much faster unless you are talking about EXTREME high-performing code. Object instantiation in modern JVMs only take a few ten nano seconds or something. Also, you could mistakenly use an ArrayList having small initial length or something and make things worse)


问:
How to find better algorithm for my prefix matcher algorithm
I was solving online problem and the task was something like this:

There are two arrays: numbers and prefixes.

Array numbers contains numbers: “+432112345”, “+9990”, “+4450505”

Array prefixes contains prefixes: “+4321”, “+43211”, “+7700”, “+4452”, “+4”

Find longest prefix for each number. If no prefix found for number, match with empty string.

For example:

“+432112345” matches with the longest prefix “+43211” (not +4321, cause 43211 is longer).

“+9990” doesn't match with anything, so empty string "".

“+4450505” matches with “+4”  (“+4452” doesn’t match because of the 2).

I came up with the most straight forward solution where I loop through each number with each prefix. So each time new number, I check prefixes, if some prefix is longer than last one, I will change.

Map<String, String> numsAndPrefixes = new HashMap<>();

for (String number : A) {
    for (String prefix : B) {
        if (number.contains(prefix)) {
            // if map already contains this number, check for prefixes.
            // if longer exists, switch longer one
            if (numsAndPrefixes.containsKey(number)) {
                int prefixLength = prefix.length();
                int currentLen = numsAndPrefixes.get(number).length();
                if (prefixLength > currentLen) {
                    numsAndPrefixes.put(number, prefix);
                }
            } else {
                numsAndPrefixes.put(number, prefix);
            }
        } else if (!number.contains(prefix) && !numsAndPrefixes.containsKey(number)){
            numsAndPrefixes.put(number, "");
        }
    }
}
```

So it will have two for loops. I see that each time I am doing the same job over and over, e.g checking for prefixes. It works, but it is slow.  The problem is that I can’t come up with anything better.

Could someone explain how they would approach to find better algorithm?

And more general, how do you proceed if you have somewhat working solution and trying to find better one? What knowledge am I still missing?

答:
I would implement this using a TreeSet and the floor(E e) method.

```<code>String[] numbers = { "+432112345", "+9990", "+4450505" };
String[] prefixes = { "+4321", "+43211", "+7700", "+4452", "+4" };

TreeSet<String> prefixSet = new TreeSet<>(Arrays.asList(prefixes));
for (String number : numbers) {
    String prefix = prefixSet.floor(number);
    while (prefix != null && ! number.startsWith(prefix))
        prefix = prefixSet.floor(prefix.substring(0, prefix.length() - 1));
    if (prefix == null)
        prefix = "";
    System.out.println(number + " -> " + prefix);
}
</code>```

Output

+432112345 -> +43211
+9990 ->
+4450505 -> +4
```

Body:
I was solving online problem and the task was something like this:

There are two arrays: numbers and prefixes.

Array numbers contains numbers: “+432112345”, “+9990”, “+4450505”

Array prefixes contains prefixes: “+4321”, “+43211”, “+7700”, “+4452”, “+4”

Find longest prefix for each number. If no prefix found for number, match with empty string.

For example:

“+432112345” matches with the longest prefix “+43211” (not +4321, cause 43211 is longer).

“+9990” doesn't match with anything, so empty string "".

“+4450505” matches with “+4”  (“+4452” doesn’t match because of the 2).

I came up with the most straight forward solution where I loop through each number with each prefix. So each time new number, I check prefixes, if some prefix is longer than last one, I will change.

Map<String, String> numsAndPrefixes = new HashMap<>();

for (String number : A) {
    for (String prefix : B) {
        if (number.contains(prefix)) {
            // if map already contains this number, check for prefixes.
            // if longer exists, switch longer one
            if (numsAndPrefixes.containsKey(number)) {
                int prefixLength = prefix.length();
                int currentLen = numsAndPrefixes.get(number).length();
                if (prefixLength > currentLen) {
                    numsAndPrefixes.put(number, prefix);
                }
            } else {
                numsAndPrefixes.put(number, prefix);
            }
        } else if (!number.contains(prefix) && !numsAndPrefixes.containsKey(number)){
            numsAndPrefixes.put(number, "");
        }
    }
}

So it will have two for loops. I see that each time I am doing the same job over and over, e.g checking for prefixes. It works, but it is slow.  The problem is that I can’t come up with anything better.

Could someone explain how they would approach to find better algorithm?

And more general, how do you proceed if you have somewhat working solution and trying to find better one? What knowledge am I still missing?

Body:
I would implement this using a TreeSet and the floor(E e) method.

String[] numbers = { "+432112345", "+9990", "+4450505" };
String[] prefixes = { "+4321", "+43211", "+7700", "+4452", "+4" };

TreeSet<String> prefixSet = new TreeSet<>(Arrays.asList(prefixes));
for (String number : numbers) {
    String prefix = prefixSet.floor(number);
    while (prefix != null && ! number.startsWith(prefix))
        prefix = prefixSet.floor(prefix.substring(0, prefix.length() - 1));
    if (prefix == null)
        prefix = "";
    System.out.println(number + " -> " + prefix);
}

Output

+432112345 -> +43211
+9990 ->
+4450505 -> +4


问:
PHPMyAdmin Designer does not show relations
When using the PHPMyAdmin Designer tool I can not see relations (lines that connect each foreign key relation). The foreign key attributes get a different icon than the other attributes, however the line connection is missing. I already tried switching on/off "Show/Hide relations".

What am I missing?

答:
You need to correct the internal table relationships and then the lines appear.

(Select each table > structure view > relations view > internal relationships > change what is wrong)

I've got a portuguese install so the names might be slightly different. I did this and the problem was solved.