问:
JavaFX Getting an IndexOutOfBoundsException selecting item in an edible ComboBox
Created an Edible Combobox, being used as a search box. When I click on an item I get a 'Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: [ fromIndex: 0, toIndex: 1, size: 0 ]'

What it should do, and it seems to do it, but with the error, is type a name in the combobox, Select a name and have that added to a table, then clear the searchbox and give it focus to accept the next name. If I comment out the line that clears the value from the combobox, "searchCB.setValue(null); // <*********** THIS CAUSES THE ERROR" I don't get the error.

TestApp.java

```<code>import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.skin.ComboBoxListViewSkin;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class TestApp extends Application {
    ObservableList<TestPerson> personList = FXCollections.observableArrayList();

    @Override
    public void start(Stage primaryStage) {
        ObservableList<TestPerson> searchList = FXCollections.observableArrayList();

        searchList.add(new TestPerson("Roger",null,"Rabbit",null));
        searchList.add(new TestPerson("Jack","The","Ripper",null));
        searchList.add(new TestPerson("Ferris",null,"Bueller",null));

        personList = FXCollections.observableArrayList();

        ComboBox<TestPerson> searchCB = new ComboBox<TestPerson>();
        searchCB.setItems(searchList);

        searchCB.setConverter(new StringConverter<TestPerson>() {

            @Override
            public String toString(TestPerson object) {
                return object != null && object.getFullName() != null?object.getFullName():"";
            }

            @Override
            public TestPerson fromString(String string) {
                return searchCB.getItems().stream().filter(o -> o.getFullName().equals(string)).findFirst().orElse(null);
            }
        });

        searchCB.setOnAction((e) -> {
            if (searchCB.getValue() != null && !searchCB.getValue().getFullName().isBlank()) {
                personList.add(searchCB.getValue());
                searchCB.setValue(null); // <*********** THIS CAUSES THE ERROR
                searchCB.requestFocus();
            }
        });

        ComboBoxListViewSkin<TestPerson> searchComboBoxSkin = new ComboBoxListViewSkin<>(searchCB);
        searchComboBoxSkin.getPopupContent().addEventFilter(KeyEvent.ANY, (event) -> {
            if (event.getCode() == KeyCode.SPACE) {
                event.consume();
            }
        });
        searchCB.setSkin(searchComboBoxSkin);

        new TestAutoCompleteComboBoxListener(searchCB);

        searchCB.setMaxWidth(Double.MAX_VALUE);
        TableView<TestPerson> listTableView = new TableView<>(personList);
        listTableView.setEditable(true);
        listTableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        listTableView.setItems(personList);

        TableColumn<TestPerson, String> fullNameColumn = new TableColumn<>();
        listTableView.getColumns().add(fullNameColumn);
        fullNameColumn.setEditable(true);
        fullNameColumn.setCellValueFactory(cellData -> cellData.getValue().fullNameProperty());
        listTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
        VBox vBox = new VBox();
        vBox.getChildren().addAll(searchCB,listTableView);

        AnchorPane anchorPane = new AnchorPane(vBox);
        Scene scene = new Scene(anchorPane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args){
        launch(args);
    }
}
</code>```

AutoCompleteComboBoxListener.java This is based on another post I found here, but was not able to get it to work as written using Generics. The toString() method wouldn't work correctly.

```<code>import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.control.ComboBox;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;

import java.util.Arrays;

public class TestAutoCompleteComboBoxListener implements EventHandler<KeyEvent>{
    private ComboBox comboBox;
    private StringBuilder sb;
    private ObservableList<TestPerson> data;
    private boolean moveCaretToPos = false;
    private int caretPos;

    public TestAutoCompleteComboBoxListener(final ComboBox<TestPerson> comboBox) {
        this.comboBox = comboBox;
        sb = new StringBuilder();
        data =  comboBox.getItems();

        this.comboBox.setEditable(true);
        this.comboBox.setOnKeyPressed(new EventHandler<KeyEvent>() {

            @Override
            public void handle(KeyEvent t) {
                comboBox.hide();
            }
        });
        this.comboBox.setOnKeyReleased(TestAutoCompleteComboBoxListener.this);
    }

    @Override
    public void handle(KeyEvent event) {
        if(event.getCode() == KeyCode.UP) {
            caretPos = -1;
            moveCaret(comboBox.getEditor().getText().length());
            return;
        } else if(event.getCode() == KeyCode.DOWN) {
            if(!comboBox.isShowing()) {
                comboBox.show();
            }
            caretPos = -1;
            moveCaret(comboBox.getEditor().getText().length());
            return;
        } else if(event.getCode() == KeyCode.BACK_SPACE) {
            moveCaretToPos = true;
            caretPos = comboBox.getEditor().getCaretPosition();
        } else if(event.getCode() == KeyCode.DELETE) {
            moveCaretToPos = true;
            caretPos = comboBox.getEditor().getCaretPosition();
        }

        if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT
                || event.isControlDown() || event.getCode() == KeyCode.HOME
                || event.getCode() == KeyCode.END || event.getCode() == KeyCode.TAB) {
            return;
        }

        ObservableList list = FXCollections.observableArrayList();

        for (TestPerson row: data) {
            if(Arrays.stream(TestAutoCompleteComboBoxListener.this.comboBox
                            .getEditor().getText().toLowerCase().split(" ", 0)).allMatch(row.getFullName().toLowerCase()::contains)) {
                list.add(row);
            }
        }

        String t = comboBox.getEditor().getText();

        comboBox.setItems(list);
        comboBox.getEditor().setText(t);
        if(!moveCaretToPos) {
            caretPos = -1;
        }
        moveCaret(t.length());
        if(!list.isEmpty()) {
            comboBox.show();
        }
    }

    private void moveCaret(int textLength) {
        if(caretPos == -1) {
            comboBox.getEditor().positionCaret(textLength);
        } else {
            comboBox.getEditor().positionCaret(caretPos);
        }
        moveCaretToPos = false;
    }
}
</code>```

TestPerson.java class

```<code>import javafx.beans.property.*;
import org.apache.commons.lang3.StringUtils;

import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TestPerson {
    private StringProperty firstName,
                            middleName,
                            lastName,
                            suffix;

    public TestPerson() {this(null, null, null, null);}
    public TestPerson(String firstName,
                      String middleName,
                      String lastName,
                      String suffix) {
        init();

        this.firstName.set(firstName);
        this.middleName.set(middleName);
        this.lastName.set(lastName);
        this.suffix.set(suffix);
    }

    private void init() {
        this.firstName = new SimpleStringProperty(null);
        this.middleName = new SimpleStringProperty(null);
        this.lastName = new SimpleStringProperty(null);
        this.suffix = new SimpleStringProperty(null);
    }

    public void setFirstName(String firstName) {
        this.firstName.set((StringUtils.isBlank(firstName)?null:firstName.trim()));
    }

    public void setMiddleName(String middleName) {
        this.middleName.set((StringUtils.isBlank(middleName)?null:middleName.trim()));
    }

    public void setLastName(String lastName) {
        this.lastName.set((StringUtils.isBlank(lastName)?null:lastName.trim()));
    }

    public void setSuffix(String suffix) {
        this.suffix.set((StringUtils.isBlank(suffix)?null:suffix.trim()));
    }

    public String getFirstName() {
        return firstName.get();
    }

    public StringProperty firstNameProperty() {
        return firstName;
    }

    public String getMiddleName() {
        return middleName.get();
    }

    public StringProperty middleNameProperty() {
        return middleName;
    }

    public String getLastName() {
        return lastName.get();
    }

    public StringProperty lastNameProperty() {
        return lastName;
    }

    public String getSuffix() {
        return suffix.get();
    }

    public StringProperty suffixProperty() {
        return suffix;
    }

    public String getFullName() {
        String joined = Stream.of(firstName.get(), middleName.get(), lastName.get(), suffix.get())
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.joining(" "));
        return joined;
    }

    public StringProperty fullNameProperty() {
        StringProperty name = new SimpleStringProperty(getFullName());

        return new SimpleStringProperty(getFullName());
    }

    @Override
    public String toString() {
        return getFullName();
    }
}
</code>```

Error

```<code>Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: [ fromIndex: 0, toIndex: 1, size: 0 ]
    at javafx.controls/com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.subList(ReadOnlyUnbackedObservableList.java:171)
    at javafx.base/javafx.collections.ListChangeListener$Change.getAddedSubList(ListChangeListener.java:243)
    at javafx.controls/com.sun.javafx.scene.control.behavior.ListViewBehavior.lambda$new$57(ListViewBehavior.java:292)
    at javafx.base/javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
    at javafx.base/com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
    at javafx.base/com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    at javafx.base/javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:239)
    at javafx.controls/com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(ReadOnlyUnbackedObservableList.java:110)
    at javafx.controls/javafx.scene.control.MultipleSelectionModelBase.clearAndSelect(MultipleSelectionModelBase.java:383)
    at javafx.controls/javafx.scene.control.ListView$ListViewBitSetSelectionModel.clearAndSelect(ListView.java:1451)
    at javafx.controls/com.sun.javafx.scene.control.behavior.CellBehaviorBase.simpleSelect(CellBehaviorBase.java:282)
    at javafx.controls/com.sun.javafx.scene.control.behavior.CellBehaviorBase.doSelect(CellBehaviorBase.java:246)
    at javafx.controls/com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(CellBehaviorBase.java:176)
    at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3897)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1878)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:557)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:943)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:833)
</code>```

答:
Got it to work by enclosing the searchCB.setValue(null) in Platform runlater.

```<code>Platform.runLater(() -> searchCB.setValue(null));
</code>```

thanks to Przemysław Długoszewski-Tamoń in another thread for the idea.

Body:
Created an Edible Combobox, being used as a search box. When I click on an item I get a 'Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: [ fromIndex: 0, toIndex: 1, size: 0 ]'

What it should do, and it seems to do it, but with the error, is type a name in the combobox, Select a name and have that added to a table, then clear the searchbox and give it focus to accept the next name. If I comment out the line that clears the value from the combobox, "searchCB.setValue(null); // <*********** THIS CAUSES THE ERROR" I don't get the error.

TestApp.java

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.skin.ComboBoxListViewSkin;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class TestApp extends Application {
    ObservableList<TestPerson> personList = FXCollections.observableArrayList();

    @Override
    public void start(Stage primaryStage) {
        ObservableList<TestPerson> searchList = FXCollections.observableArrayList();

        searchList.add(new TestPerson("Roger",null,"Rabbit",null));
        searchList.add(new TestPerson("Jack","The","Ripper",null));
        searchList.add(new TestPerson("Ferris",null,"Bueller",null));

        personList = FXCollections.observableArrayList();

        ComboBox<TestPerson> searchCB = new ComboBox<TestPerson>();
        searchCB.setItems(searchList);

        searchCB.setConverter(new StringConverter<TestPerson>() {

            @Override
            public String toString(TestPerson object) {
                return object != null && object.getFullName() != null?object.getFullName():"";
            }

            @Override
            public TestPerson fromString(String string) {
                return searchCB.getItems().stream().filter(o -> o.getFullName().equals(string)).findFirst().orElse(null);
            }
        });

        searchCB.setOnAction((e) -> {
            if (searchCB.getValue() != null && !searchCB.getValue().getFullName().isBlank()) {
                personList.add(searchCB.getValue());
                searchCB.setValue(null); // <*********** THIS CAUSES THE ERROR
                searchCB.requestFocus();
            }
        });

        ComboBoxListViewSkin<TestPerson> searchComboBoxSkin = new ComboBoxListViewSkin<>(searchCB);
        searchComboBoxSkin.getPopupContent().addEventFilter(KeyEvent.ANY, (event) -> {
            if (event.getCode() == KeyCode.SPACE) {
                event.consume();
            }
        });
        searchCB.setSkin(searchComboBoxSkin);

        new TestAutoCompleteComboBoxListener(searchCB);

        searchCB.setMaxWidth(Double.MAX_VALUE);
        TableView<TestPerson> listTableView = new TableView<>(personList);
        listTableView.setEditable(true);
        listTableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        listTableView.setItems(personList);

        TableColumn<TestPerson, String> fullNameColumn = new TableColumn<>();
        listTableView.getColumns().add(fullNameColumn);
        fullNameColumn.setEditable(true);
        fullNameColumn.setCellValueFactory(cellData -> cellData.getValue().fullNameProperty());
        listTableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
        VBox vBox = new VBox();
        vBox.getChildren().addAll(searchCB,listTableView);

        AnchorPane anchorPane = new AnchorPane(vBox);
        Scene scene = new Scene(anchorPane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args){
        launch(args);
    }
}

AutoCompleteComboBoxListener.java This is based on another post I found here, but was not able to get it to work as written using Generics. The toString() method wouldn't work correctly.

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.control.ComboBox;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;

import java.util.Arrays;

public class TestAutoCompleteComboBoxListener implements EventHandler<KeyEvent>{
    private ComboBox comboBox;
    private StringBuilder sb;
    private ObservableList<TestPerson> data;
    private boolean moveCaretToPos = false;
    private int caretPos;

    public TestAutoCompleteComboBoxListener(final ComboBox<TestPerson> comboBox) {
        this.comboBox = comboBox;
        sb = new StringBuilder();
        data =  comboBox.getItems();

        this.comboBox.setEditable(true);
        this.comboBox.setOnKeyPressed(new EventHandler<KeyEvent>() {

            @Override
            public void handle(KeyEvent t) {
                comboBox.hide();
            }
        });
        this.comboBox.setOnKeyReleased(TestAutoCompleteComboBoxListener.this);
    }

    @Override
    public void handle(KeyEvent event) {
        if(event.getCode() == KeyCode.UP) {
            caretPos = -1;
            moveCaret(comboBox.getEditor().getText().length());
            return;
        } else if(event.getCode() == KeyCode.DOWN) {
            if(!comboBox.isShowing()) {
                comboBox.show();
            }
            caretPos = -1;
            moveCaret(comboBox.getEditor().getText().length());
            return;
        } else if(event.getCode() == KeyCode.BACK_SPACE) {
            moveCaretToPos = true;
            caretPos = comboBox.getEditor().getCaretPosition();
        } else if(event.getCode() == KeyCode.DELETE) {
            moveCaretToPos = true;
            caretPos = comboBox.getEditor().getCaretPosition();
        }

        if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT
                || event.isControlDown() || event.getCode() == KeyCode.HOME
                || event.getCode() == KeyCode.END || event.getCode() == KeyCode.TAB) {
            return;
        }

        ObservableList list = FXCollections.observableArrayList();

        for (TestPerson row: data) {
            if(Arrays.stream(TestAutoCompleteComboBoxListener.this.comboBox
                            .getEditor().getText().toLowerCase().split(" ", 0)).allMatch(row.getFullName().toLowerCase()::contains)) {
                list.add(row);
            }
        }

        String t = comboBox.getEditor().getText();

        comboBox.setItems(list);
        comboBox.getEditor().setText(t);
        if(!moveCaretToPos) {
            caretPos = -1;
        }
        moveCaret(t.length());
        if(!list.isEmpty()) {
            comboBox.show();
        }
    }

    private void moveCaret(int textLength) {
        if(caretPos == -1) {
            comboBox.getEditor().positionCaret(textLength);
        } else {
            comboBox.getEditor().positionCaret(caretPos);
        }
        moveCaretToPos = false;
    }
}

TestPerson.java class

import javafx.beans.property.*;
import org.apache.commons.lang3.StringUtils;

import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TestPerson {
    private StringProperty firstName,
                            middleName,
                            lastName,
                            suffix;

    public TestPerson() {this(null, null, null, null);}
    public TestPerson(String firstName,
                      String middleName,
                      String lastName,
                      String suffix) {
        init();

        this.firstName.set(firstName);
        this.middleName.set(middleName);
        this.lastName.set(lastName);
        this.suffix.set(suffix);
    }

    private void init() {
        this.firstName = new SimpleStringProperty(null);
        this.middleName = new SimpleStringProperty(null);
        this.lastName = new SimpleStringProperty(null);
        this.suffix = new SimpleStringProperty(null);
    }

    public void setFirstName(String firstName) {
        this.firstName.set((StringUtils.isBlank(firstName)?null:firstName.trim()));
    }

    public void setMiddleName(String middleName) {
        this.middleName.set((StringUtils.isBlank(middleName)?null:middleName.trim()));
    }

    public void setLastName(String lastName) {
        this.lastName.set((StringUtils.isBlank(lastName)?null:lastName.trim()));
    }

    public void setSuffix(String suffix) {
        this.suffix.set((StringUtils.isBlank(suffix)?null:suffix.trim()));
    }

    public String getFirstName() {
        return firstName.get();
    }

    public StringProperty firstNameProperty() {
        return firstName;
    }

    public String getMiddleName() {
        return middleName.get();
    }

    public StringProperty middleNameProperty() {
        return middleName;
    }

    public String getLastName() {
        return lastName.get();
    }

    public StringProperty lastNameProperty() {
        return lastName;
    }

    public String getSuffix() {
        return suffix.get();
    }

    public StringProperty suffixProperty() {
        return suffix;
    }

    public String getFullName() {
        String joined = Stream.of(firstName.get(), middleName.get(), lastName.get(), suffix.get())
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.joining(" "));
        return joined;
    }

    public StringProperty fullNameProperty() {
        StringProperty name = new SimpleStringProperty(getFullName());

        return new SimpleStringProperty(getFullName());
    }

    @Override
    public String toString() {
        return getFullName();
    }
}

Error

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: [ fromIndex: 0, toIndex: 1, size: 0 ]
    at javafx.controls/com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.subList(ReadOnlyUnbackedObservableList.java:171)
    at javafx.base/javafx.collections.ListChangeListener$Change.getAddedSubList(ListChangeListener.java:243)
    at javafx.controls/com.sun.javafx.scene.control.behavior.ListViewBehavior.lambda$new$57(ListViewBehavior.java:292)
    at javafx.base/javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
    at javafx.base/com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
    at javafx.base/com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    at javafx.base/javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:239)
    at javafx.controls/com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(ReadOnlyUnbackedObservableList.java:110)
    at javafx.controls/javafx.scene.control.MultipleSelectionModelBase.clearAndSelect(MultipleSelectionModelBase.java:383)
    at javafx.controls/javafx.scene.control.ListView$ListViewBitSetSelectionModel.clearAndSelect(ListView.java:1451)
    at javafx.controls/com.sun.javafx.scene.control.behavior.CellBehaviorBase.simpleSelect(CellBehaviorBase.java:282)
    at javafx.controls/com.sun.javafx.scene.control.behavior.CellBehaviorBase.doSelect(CellBehaviorBase.java:246)
    at javafx.controls/com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(CellBehaviorBase.java:176)
    at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3897)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1878)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2623)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:557)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:943)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:833)

Body:
Got it to work by enclosing the searchCB.setValue(null) in Platform runlater.

Platform.runLater(() -> searchCB.setValue(null));

thanks to Przemysław Długoszewski-Tamoń in another thread for the idea.


来源: stackexchange

问:
Mat Chip List opon selection expands input
Giving the default behavior, when value is selected from a dropdown, MatChip appears within the input, but also expands it. I am a bit surprised this is the default behavior. Anyone can suggest how they fix it? Providing a forked StackBlitz demo (source take from Angular Material documentation):

DEMO

You can see in the images bellow - when chip selected, input becomes taller.

答:
Problem

The problem is mat-form-field-infix class. When there are chips in the input, they increase the height.

Solution

You can set the minimal height for that class to be the same as when there are chips in the input. You can do it in the CSS file like this:

::ng-deep .mat-form-field-infix {
  min-height: 32px;
}
```

Working example

ContentLicense: CC BY-SA 4.0

Body:
Problem

The problem is mat-form-field-infix class. When there are chips in the input, they increase the height.

Solution

You can set the minimal height for that class to be the same as when there are chips in the input. You can do it in the CSS file like this:

::ng-deep .mat-form-field-infix {
  min-height: 32px;
}

Working example


问:
How to disable other buttons onclick for a short period of time
i have simple quizz project where i fetch data of questions and answers my problem is when i click on one of the answers i want other buttons to be disabled because if someone keeps pressing on other options the quiz will rapidly change questions. i want to disable other answer options when i clik on the  answer and then after the next question generates enable them again and so on</p>
```<code>
import './App.css';
import axios from 'axios'
import {useState,useEffect} from 'react'

function App() {
  const [quiz,setQuiz] = useState([])
  const [answer,setAnswer] = useState([])
  const [correct,setCorrect] =useState('')
  const [points,setPoints] = useState(0)
  const [turns,setTurns] = useState(0)
  const [disabled,setDisabled] = useState(false)

  function refreshPage() {
    window.location.reload(false);
  }

  useEffect(()=>{
    axios.get('https://opentdb.com/api.php?amount=10')
    .then(res =>{
       setQuiz(res.data.results[0])
       let tempVar = res.data.results[0] ;
       setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
      setCorrect(tempVar.correct_answer)
      console.log(res.data)
      console.log(answer)

    })
    .catch(err=>{
      console.log(err);
    })
  },[])

  const  handleClick = (e) =>{
    setDisabled(true)
    if(disabled && e.target.innerText === correct){

      setPoints(points + 1)
      setTurns(turns + 1)
      e.target.style.background = 'green'
      setTimeout(() => e.target.style.background = '', 2000);

      setTimeout(() => {
        axios.get('https://opentdb.com/api.php?amount=10')
        .then(res=>{
           setQuiz(res.data.results[0])
           let tempVar = res.data.results[0] ;
           setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
          setCorrect(tempVar.correct_answer)
      })
      .catch(err=>{
        console.log(err);
      })
    }, 2000);
    console.log(points)
    } else if(e.target.innerText !== correct){
      setTurns(turns + 1)
      e.target.style.background = 'red'
     setTimeout(() => e.target.style.background='', 2000);

      setTimeout(() => {
        axios.get('https://opentdb.com/api.php?amount=10')
        .then(res=>{
           setQuiz(res.data.results[0])
           let tempVar = res.data.results[0] ;
           setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
          setCorrect(tempVar.correct_answer)
      })
      .catch(err=>{
        console.log(err);
      })
    }, 2000);
    }
    }

if(points >= 10|| turns >= 10){
  return (
    <div className='score'>
      <h1>Well done !</h1>
     <p>Your Score: {points}</p>
      <button className='button-28' onClick={refreshPage}>New Test</button>
    </div>
  )
}

  return (
    <div className="App">
     <div className='grid'>
   <h1>{quiz.question}</h1>
   { answer?.map(answers =>
   <button className='button-28' onClick={handleClick}key={answers}>{answers}</button>
   )
   }

    </div>
    </div>

  );
}

export default App;
</code>```

答:
You can update your disabled state after you update your answers and correct. And use that state as disabled = true/false in your buttons

```<code>import './App.css';
import axios from 'axios'
import {useState,useEffect} from 'react'

function App() {
  const [quiz,setQuiz] = useState([])
  const [answer,setAnswer] = useState([])
  const [correct,setCorrect] =useState('')
  const [points,setPoints] = useState(0)
  const [turns,setTurns] = useState(0)
  const [disabled,setDisabled] = useState(false)

  function refreshPage() {
    window.location.reload(false);
  }

  useEffect(()=>{
    axios.get('https://opentdb.com/api.php?amount=10')
    .then(res =>{
       setQuiz(res.data.results[0])
       let tempVar = res.data.results[0] ;
       setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
      setCorrect(tempVar.correct_answer)
      console.log(res.data)
      console.log(answer)

    })
    .catch(err=>{
      console.log(err);
    })
  },[])

  const  handleClick = (e) =>{
    setDisabled(true)
    if(disabled && e.target.innerText === correct){

      setPoints(points + 1)
      setTurns(turns + 1)
      e.target.style.background = 'green'
      setTimeout(() => e.target.style.background = '', 2000);

      setTimeout(() => {
        axios.get('https://opentdb.com/api.php?amount=10')
        .then(res=>{
           setQuiz(res.data.results[0])
           let tempVar = res.data.results[0] ;
           setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
          setCorrect(tempVar.correct_answer)
          setDisabled(false)
      })
      .catch(err=>{
        console.log(err);
        setDisabled(false)
      })
    }, 2000);
    console.log(points)
    } else if(e.target.innerText !== correct){
      setTurns(turns + 1)
      e.target.style.background = 'red'
     setTimeout(() => e.target.style.background='', 2000);

      setTimeout(() => {
        axios.get('https://opentdb.com/api.php?amount=10')
        .then(res=>{
           setQuiz(res.data.results[0])
           let tempVar = res.data.results[0] ;
           setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
          setCorrect(tempVar.correct_answer)
          setDisabled(false)
      })
      .catch(err=>{
        console.log(err);
        setDisabled(false)
      })
    }, 2000);
    }
    }

if(points >= 10|| turns >= 10){
  return (
    <div className='score'>
      <h1>Well done !</h1>
     <p>Your Score: {points}</p>
      <button className='button-28' onClick={refreshPage}>New Test</button>
    </div>
  )
}

  return (
    <div className="App">
     <div className='grid'>
   <h1>{quiz.question}</h1>
   { answer?.map(answers =>
   <button className='button-28' onClick={handleClick}key={answers} disabled={disabled}>{answers}</button>
   )
   }

    </div>
    </div>

  );
}

export default App;
</code>```

Body:
i have simple quizz project where i fetch data of questions and answers my problem is when i click on one of the answers i want other buttons to be disabled because if someone keeps pressing on other options the quiz will rapidly change questions. i want to disable other answer options when i clik on the  answer and then after the next question generates enable them again and so on

import './App.css';
import axios from 'axios'
import {useState,useEffect} from 'react'

function App() {
  const [quiz,setQuiz] = useState([])
  const [answer,setAnswer] = useState([])
  const [correct,setCorrect] =useState('')
  const [points,setPoints] = useState(0)
  const [turns,setTurns] = useState(0)
  const [disabled,setDisabled] = useState(false)

  function refreshPage() {
    window.location.reload(false);
  }

  useEffect(()=>{
    axios.get('https://opentdb.com/api.php?amount=10')
    .then(res =>{
       setQuiz(res.data.results[0])
       let tempVar = res.data.results[0] ;
       setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
      setCorrect(tempVar.correct_answer)
      console.log(res.data)
      console.log(answer)

    })
    .catch(err=>{
      console.log(err);
    })
  },[])

  const  handleClick = (e) =>{
    setDisabled(true)
    if(disabled && e.target.innerText === correct){

      setPoints(points + 1)
      setTurns(turns + 1)
      e.target.style.background = 'green'
      setTimeout(() => e.target.style.background = '', 2000);

      setTimeout(() => {
        axios.get('https://opentdb.com/api.php?amount=10')
        .then(res=>{
           setQuiz(res.data.results[0])
           let tempVar = res.data.results[0] ;
           setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
          setCorrect(tempVar.correct_answer)
      })
      .catch(err=>{
        console.log(err);
      })
    }, 2000);
    console.log(points)
    } else if(e.target.innerText !== correct){
      setTurns(turns + 1)
      e.target.style.background = 'red'
     setTimeout(() => e.target.style.background='', 2000);

      setTimeout(() => {
        axios.get('https://opentdb.com/api.php?amount=10')
        .then(res=>{
           setQuiz(res.data.results[0])
           let tempVar = res.data.results[0] ;
           setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
          setCorrect(tempVar.correct_answer)
      })
      .catch(err=>{
        console.log(err);
      })
    }, 2000);
    }
    }

if(points >= 10|| turns >= 10){
  return (

Well done !

Your Score: {points}

      <button className='button-28' onClick={refreshPage}>New Test</button>

  )
}

  return (

{quiz.question}

   { answer?.map(answers =>
   <button className='button-28' onClick={handleClick}key={answers}>{answers}</button>
   )
   }

  );
}

export default App;

Body:
You can update your disabled state after you update your answers and correct. And use that state as disabled = true/false in your buttons

import './App.css';
import axios from 'axios'
import {useState,useEffect} from 'react'

function App() {
  const [quiz,setQuiz] = useState([])
  const [answer,setAnswer] = useState([])
  const [correct,setCorrect] =useState('')
  const [points,setPoints] = useState(0)
  const [turns,setTurns] = useState(0)
  const [disabled,setDisabled] = useState(false)

  function refreshPage() {
    window.location.reload(false);
  }

  useEffect(()=>{
    axios.get('https://opentdb.com/api.php?amount=10')
    .then(res =>{
       setQuiz(res.data.results[0])
       let tempVar = res.data.results[0] ;
       setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
      setCorrect(tempVar.correct_answer)
      console.log(res.data)
      console.log(answer)

    })
    .catch(err=>{
      console.log(err);
    })
  },[])

  const  handleClick = (e) =>{
    setDisabled(true)
    if(disabled && e.target.innerText === correct){

      setPoints(points + 1)
      setTurns(turns + 1)
      e.target.style.background = 'green'
      setTimeout(() => e.target.style.background = '', 2000);

      setTimeout(() => {
        axios.get('https://opentdb.com/api.php?amount=10')
        .then(res=>{
           setQuiz(res.data.results[0])
           let tempVar = res.data.results[0] ;
           setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
          setCorrect(tempVar.correct_answer)
          setDisabled(false)
      })
      .catch(err=>{
        console.log(err);
        setDisabled(false)
      })
    }, 2000);
    console.log(points)
    } else if(e.target.innerText !== correct){
      setTurns(turns + 1)
      e.target.style.background = 'red'
     setTimeout(() => e.target.style.background='', 2000);

      setTimeout(() => {
        axios.get('https://opentdb.com/api.php?amount=10')
        .then(res=>{
           setQuiz(res.data.results[0])
           let tempVar = res.data.results[0] ;
           setAnswer([...tempVar.incorrect_answers,tempVar.correct_answer].sort(()=>Math.random() - 0.5))
          setCorrect(tempVar.correct_answer)
          setDisabled(false)
      })
      .catch(err=>{
        console.log(err);
        setDisabled(false)
      })
    }, 2000);
    }
    }

if(points >= 10|| turns >= 10){
  return (
    <div className='score'>
      <h1>Well done !</h1>
     <p>Your Score: {points}</p>
      <button className='button-28' onClick={refreshPage}>New Test</button>
    </div>
  )
}

  return (
    <div className="App">
     <div className='grid'>
   <h1>{quiz.question}</h1>
   { answer?.map(answers =>
   <button className='button-28' onClick={handleClick}key={answers} disabled={disabled}>{answers}</button>
   )
   }

    </div>
    </div>

  );
}

export default App;


问:
Problem with Laravel Livewire : Attempt to read property "recipes" on array
I'm trying to do a search input from 2 datatables of my database, one containing vegetables and the other one containing recipes made of vegetables, i first made my search input with only the elements from the vegetable table. But now im trying to include the repice table but it wont work: I'm getting the error "Attempt to read property "recipes" on array" but I do't understand where the problem comes from.

This is my code:

Search.php:

```<code><?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Vegetable;

class Search extends Component
{
    public $query = '';

    public $vegetables;
    public $recipes;

    public function updatedQuery()
    {
        $this->vegetables = Vegetable::where('name', 'like', '%'.$this->query.'%')->get()->toArray();
    }

    public function render()
    {
        return view('livewire.search');
    }
}
</code>```

search.blade.php :

```<code><div class="searchcomponent">
    <h1>Recherche</h1>
    <input wire:model="query" type="text" placeholder="Rechercher...">

    @if(!empty($query))
        <ul>
            @if(!empty($vegetables))
                <div class="vegetables">

                    @foreach($vegetables as $vegetable)
                        <li><span class="material-icons">lunch_dining</span>{{ $vegetable['name'] }}</li>
                    @endforeach

                </div>
            @else
                <li>Pas de résultat</li>
            @endif

            <div class="recipes">

                @foreach($vegetables as $vegetable)
                    @foreach($vegetable->recipes as $recipe)
                        <li><span class="material-icons">menu_book</span>{{ $recipe['name'] }}<span class="ingredient">Ingrédient: {{ $vegetable['name'] }}</span></li>
                    @endforeach
                @endforeach
            </div>
        </ul>
    @endif
</div>
</code>```

My model Vegetable :

```<code><?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Vegetable extends Model
{
    use HasFactory;

    public $timestamps = false;

    protected $fillable = ['name'];

    public function recipes(){
        return $this->belongsToMany(Recipe::class, 'vegetables_recipes', 'vegetable_id', 'recipe_id');
    }

    public function getName($id) {
        return $this->name;
    }
}
</code>```

My model Recipe :

```<code><?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Recipe extends Model
{
    use HasFactory;
    public $timestamps = false;

    protected $fillable = ['name'];

    public function vegetables(){
        return $this->hasOne(Vegetable::class, 'vegetables_recipes', 'recipe_id', 'vegetable_id');
    }

    public function getName($id) {
        return $this->name;
    }
}
</code>```

The model from my pivot table VegetablesRecipe :

```<code><?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class VegetablesRecipe extends Model
{
    use HasFactory;

    public $timestamps = false;

    protected $fillable = ['vegetable_id', 'recipe_id'];
}
</code>```

Thank you in advance

答:
So I found the issue with your code; I didn't notice it yesterday as it was hidden off-screen in your Search.php's updatedQuery() function:

$this->vegetables = Vegetable::where('name', 'like', '%'.$this->query.'%')
->get()
->toArray();
```
<p>When you call <code>->toArray()</code>, you convert the Collection of <code>Vegetable</code> Model instances into an Array of Arrays. This means you cannot use Object Access to get Properties:</p>
<pre class="lang-php prettyprint-override"><code>$vegetable->recipes; // Fails with error "Attempt to read property "recipes" on array"
</code>```

Additionally, you cannot access any Model functions, as an Array is not an instance of a Model:

$vegetables['recipes']; // Undefined array key "recipes"
```
<p>Since <code>public function recipes()</code> is a method of the <code>Vegetable.php</code> Model class, that won't work. It <em>can</em> work, if you load it first <em>before</em> casting to an Array:</p>
<pre class="lang-php prettyprint-override"><code>$this->vegetables = Vegetable::where('name', 'like', '%'.$this->query.'%')
->with('recipes')
->get()
->toArray();
</code>```

Now, $vegetable['recipes'] will work, but it's better to just drop the ->toArray() completely:

$this->vegetables = Vegetable::where('name', 'like', '%'.$this->query.'%')
->with('recipes')
->get();
```
<p>Additionally, for performance reasons, you want to include <code>->with('recipes')</code> to prevent N+1 queries being called while looping.</p>
<p>With those changes made, you can write your <code>livewire/search.blade.php</code> code as follows:</p>
```

Recherche

  <input wire:model="query" type="text" placeholder="Rechercher...">
  @if(!empty($query))

      @if(!empty($vegetables))

          @foreach($vegetables as $vegetable)

lunch_dining{{ $vegetable->name }}

          @endforeach

      @else

Pas de résultat

      @endif

        @foreach($vegetables as $vegetable)
          @foreach($vegetable->recipes as $recipe)

menu_book{{ $recipe->name }}Ingrédient: {{ $vegetable->name }}

          @endforeach
        @endforeach

  @endif

```
<p>Lastly, some cleanup:</p>
<p><code>Vegetable.php</code> and <code>Recipe.php</code></p>
<p>The methods <code>getName($id)</code> have no purpose; you're not doing anything with <code>$id</code>, and <code>name</code> is not a private property; you can simply do <code>$vegetable->name</code> or <code>$recipe->name</code> and it will do the same as what these methods are doing.</p>
<p><code>Recipe.php</code></p>
<p>As stated in the comments, <code>belongsToMany()</code> is the inverse of <code>belongsToMany()</code>, not <code>hasOne()</code>:</p>
<pre class="lang-php prettyprint-override"><code>public function vegetables(){
  return $this->belongsToMany(Vegetable::class, 'vegetables_recipes');
}
</code>```

Additionally, if the primary and foreign key names match the model names, you don't need them. The proper name for the pivot table would be recipes_vegetables (plural, alphabetical), so specifying that is required. You can do the same for Vegetable.php:

public function recipes(){
  return $this->belongsToMany(Recipe::class, 'vegetables_recipes');
}
```

Lastly, your model VegetablesRecipe.php is not needed, and is currently not being used. You typically don't define a Model for a Pivot table, so you can either remove it, or keep it around should you ever need to directly modify the Pivot.

Body:
I'm trying to do a search input from 2 datatables of my database, one containing vegetables and the other one containing recipes made of vegetables, i first made my search input with only the elements from the vegetable table. But now im trying to include the repice table but it wont work: I'm getting the error "Attempt to read property "recipes" on array" but I do't understand where the problem comes from.

This is my code:

Search.php:

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Vegetable;

class Search extends Component
{
    public $query = '';

    public $vegetables;
    public $recipes;

    public function updatedQuery()
    {
        $this->vegetables = Vegetable::where('name', 'like', '%'.$this->query.'%')->get()->toArray();
    }

    public function render()
    {
        return view('livewire.search');
    }
}

search.blade.php :

Recherche

    <input wire:model="query" type="text" placeholder="Rechercher...">

    @if(!empty($query))

            @if(!empty($vegetables))

                    @foreach($vegetables as $vegetable)

lunch_dining{{ $vegetable['name'] }}

                    @endforeach

            @else

Pas de résultat

            @endif

                @foreach($vegetables as $vegetable)
                    @foreach($vegetable->recipes as $recipe)

menu_book{{ $recipe['name'] }}Ingrédient: {{ $vegetable['name'] }}

                    @endforeach
                @endforeach

    @endif

My model Vegetable :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Vegetable extends Model
{
    use HasFactory;

    public $timestamps = false;

    protected $fillable = ['name'];

    public function recipes(){
        return $this->belongsToMany(Recipe::class, 'vegetables_recipes', 'vegetable_id', 'recipe_id');
    }

    public function getName($id) {
        return $this->name;
    }
}

My model Recipe :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Recipe extends Model
{
    use HasFactory;
    public $timestamps = false;

    protected $fillable = ['name'];

    public function vegetables(){
        return $this->hasOne(Vegetable::class, 'vegetables_recipes', 'recipe_id', 'vegetable_id');
    }

    public function getName($id) {
        return $this->name;
    }
}

The model from my pivot table VegetablesRecipe :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class VegetablesRecipe extends Model
{
    use HasFactory;

    public $timestamps = false;

    protected $fillable = ['vegetable_id', 'recipe_id'];
}

Thank you in advance

Body:
So I found the issue with your code; I didn't notice it yesterday as it was hidden off-screen in your Search.php's updatedQuery() function:

$this->vegetables = Vegetable::where('name', 'like', '%'.$this->query.'%')
->get()
->toArray();

When you call ->toArray(), you convert the Collection of Vegetable Model instances into an Array of Arrays. This means you cannot use Object Access to get Properties:

$vegetable->recipes; // Fails with error "Attempt to read property "recipes" on array"

Additionally, you cannot access any Model functions, as an Array is not an instance of a Model:

$vegetables['recipes']; // Undefined array key "recipes"

Since public function recipes() is a method of the Vegetable.php Model class, that won't work. It can work, if you load it first before casting to an Array:

$this->vegetables = Vegetable::where('name', 'like', '%'.$this->query.'%')
->with('recipes')
->get()
->toArray();

Now, $vegetable['recipes'] will work, but it's better to just drop the ->toArray() completely:

$this->vegetables = Vegetable::where('name', 'like', '%'.$this->query.'%')
->with('recipes')
->get();

Additionally, for performance reasons, you want to include ->with('recipes') to prevent N+1 queries being called while looping.

With those changes made, you can write your livewire/search.blade.php code as follows:

<div class="searchcomponent">
  <h1>Recherche</h1>
  <input wire:model="query" type="text" placeholder="Rechercher...">
  @if(!empty($query))
    <ul>
      @if(!empty($vegetables))
        <div class="vegetables">
          @foreach($vegetables as $vegetable)
            <li><span class="material-icons">lunch_dining</span>{{ $vegetable->name }}</li>
          @endforeach
        </div>
      @else
        <li>Pas de résultat</li>
      @endif
      <div class="recipes">
        @foreach($vegetables as $vegetable)
          @foreach($vegetable->recipes as $recipe)
            <li><span class="material-icons">menu_book</span>{{ $recipe->name }}<span class="ingredient">Ingrédient: {{ $vegetable->name }}</span></li>
          @endforeach
        @endforeach
      </div>
    </ul>
  @endif
</div>

Lastly, some cleanup:

Vegetable.php and Recipe.php

The methods getName($id) have no purpose; you're not doing anything with $id, and name is not a private property; you can simply do $vegetable->name or $recipe->name and it will do the same as what these methods are doing.

Recipe.php

As stated in the comments, belongsToMany() is the inverse of belongsToMany(), not hasOne():

public function vegetables(){
  return $this->belongsToMany(Vegetable::class, 'vegetables_recipes');
}

Additionally, if the primary and foreign key names match the model names, you don't need them. The proper name for the pivot table would be recipes_vegetables (plural, alphabetical), so specifying that is required. You can do the same for Vegetable.php:

public function recipes(){
  return $this->belongsToMany(Recipe::class, 'vegetables_recipes');
}

Lastly, your model VegetablesRecipe.php is not needed, and is currently not being used. You typically don't define a Model for a Pivot table, so you can either remove it, or keep it around should you ever need to directly modify the Pivot.


问:
Google Charts how to filter charts based on month and year?
I want to implement an AreaChart where I can filter based on months. For example I want to filter in the period 2021-1 till 2021-5 without a day because I retrieve a total value per specific month. The year and month is not recognized as Date and the filter is not working.
How can I make this work?

HTML:

```<code>   <div id="dashboard_div">
   <div id="filter_div"></div>
   <div id="graph-month"></div>
   </div>
</code>```

JQuery:

```<code>        function drawAreaChart(){
            google.charts.load('current', {'packages': ['corechart', 'controls', 'table']});

        google.charts.setOnLoadCallback(drawChart);

        function drawChart() {
            $.ajax({
                type: 'GET',
                url: 'testurl',
                dataType: "json",
                success: function (result) {

                    var data = new google.visualization.DataTable();

                    // Create a dashboard.
                    var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_div'));

                    data.addColumn('number', 'month');
                    data.addColumn('number', 'Total');

                   // This is the json I retrieve from the AJAX call

                     var jsondata = [{"year":2021,"month":1,"total":3242},
                     {"year":2021,"month":2,"total":2134},
                     {"year":2021,"month":3,"total":2321}];

                    $.each(result, function (index, row) {
                        data.addRow([
                            parseFloat(new Date(row.year, row.month)),
                            parseFloat(row.total)
                        ]);
                    });

                    var filter = new google.visualization.ControlWrapper({
                        'controlType': 'NumberRangeFilter',
                        'containerId': 'filter_div',
                        'options': {
                            'filterColumnLabel': 'month'},
                        'ui': {
                            'allowTyping': false,
                            'allowMultiple': false,
                            'labelStacking': 'vertical'
                        }
                    });

                    // Create a pie chart, passing some options
                            var aChart = new google.visualization.ChartWrapper({
                                'chartType': 'AreaChart',
                                'containerId': 'graph-month',
                                'options': {
                                    'pieSliceText': 'value',
                                    'legend': 'right'
                                }
                            });

                    dashboard.bind(filter, aChart );

                    var options = {
                        title: 'Total per month',
                        hAxis: {title: ,
                        vAxis: {minValue: 0}
                    };

                    dashboard.draw(data, options);

                }
            });
         }
        }
</code>```

答:
looks like you're forcing the date to be a number,

you can definitely use a date instead...

here, change the type when adding the column to date...

```<code>data.addColumn('date', 'month');
data.addColumn('number', 'Total');
</code>```

then when adding the rows, remove parseFloat from the date...

```<code>$.each(result, function (index, row) {
  data.addRow([
    new Date(row.year, row.month),
    parseFloat(row.total)
  ]);
});
</code>```

then you should be able to use a DateRangeFilter, here...

```<code>var filter = new google.visualization.ControlWrapper({
    'controlType': 'DateRangeFilter',
    'containerId': 'filter_div',
    'options': {
        'filterColumnLabel': 'month'},
    'ui': {
        'allowTyping': false,
        'allowMultiple': false,
        'labelStacking': 'vertical'
    }
});
</code>```

Body:
I want to implement an AreaChart where I can filter based on months. For example I want to filter in the period 2021-1 till 2021-5 without a day because I retrieve a total value per specific month. The year and month is not recognized as Date and the filter is not working.
How can I make this work?

HTML:

JQuery:

        function drawAreaChart(){
            google.charts.load('current', {'packages': ['corechart', 'controls', 'table']});

        google.charts.setOnLoadCallback(drawChart);

        function drawChart() {
            $.ajax({
                type: 'GET',
                url: 'testurl',
                dataType: "json",
                success: function (result) {

                    var data = new google.visualization.DataTable();

                    // Create a dashboard.
                    var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_div'));

                    data.addColumn('number', 'month');
                    data.addColumn('number', 'Total');

                   // This is the json I retrieve from the AJAX call

                     var jsondata = [{"year":2021,"month":1,"total":3242},
                     {"year":2021,"month":2,"total":2134},
                     {"year":2021,"month":3,"total":2321}];

                    $.each(result, function (index, row) {
                        data.addRow([
                            parseFloat(new Date(row.year, row.month)),
                            parseFloat(row.total)
                        ]);
                    });

                    var filter = new google.visualization.ControlWrapper({
                        'controlType': 'NumberRangeFilter',
                        'containerId': 'filter_div',
                        'options': {
                            'filterColumnLabel': 'month'},
                        'ui': {
                            'allowTyping': false,
                            'allowMultiple': false,
                            'labelStacking': 'vertical'
                        }
                    });

                    // Create a pie chart, passing some options
                            var aChart = new google.visualization.ChartWrapper({
                                'chartType': 'AreaChart',
                                'containerId': 'graph-month',
                                'options': {
                                    'pieSliceText': 'value',
                                    'legend': 'right'
                                }
                            });

                    dashboard.bind(filter, aChart );

                    var options = {
                        title: 'Total per month',
                        hAxis: {title: ,
                        vAxis: {minValue: 0}
                    };

                    dashboard.draw(data, options);

                }
            });
         }
        }

Body:
looks like you're forcing the date to be a number,

you can definitely use a date instead...

here, change the type when adding the column to date...

data.addColumn('date', 'month');
data.addColumn('number', 'Total');

then when adding the rows, remove parseFloat from the date...

$.each(result, function (index, row) {
  data.addRow([
    new Date(row.year, row.month),
    parseFloat(row.total)
  ]);
});

then you should be able to use a DateRangeFilter, here...

var filter = new google.visualization.ControlWrapper({
    'controlType': 'DateRangeFilter',
    'containerId': 'filter_div',
    'options': {
        'filterColumnLabel': 'month'},
    'ui': {
        'allowTyping': false,
        'allowMultiple': false,
        'labelStacking': 'vertical'
    }
});


问:
How can I sort a JPA query result where the parameter is a String and the result is a List of Objects?
I'm writing a Spring Boot API endpoint and I need to return a list of Airlines ordered by a String (description) of 3 or more chars, the List must be sorted with the results that match the String at the beginning of the word at the top and the rest by alphabetical order

Airline class:

```<code>@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "airline")
public class Airline implements Serializable {
    private static final long serialVersionUID = -5962418077659300886L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @Column
    private String code;

    @Column
    private String description;
}
</code>```

I get the list that matches the String but I cannot get the order right

AirlineRepository

```<code>public interface AirlineRepository extends JpaRepository<Airline, Integer> {
    Airline getById(Integer id);

    List<Airline> findByDescriptionContainingIgnoreCase(String description, Pageable pageable);
    List<Airline> findByDescriptionStartsWithIgnoreCase(String description, Pageable pageable);
}
</code>```

If I search the keyword 'ala' all airlines whose name starts with 'ala' should come first.

This is what I get

```<code>{
  "status": "SUCCESS",
  "message": "Execution Successful",
  "totalCount": 10,
  "content": [
    {
      "id": 962,
      "code": "6T",
      "description": "Air Mandalay"
    },
    {
      "id": 46,
      "code": "NZ",
      "description": "Air New Zealand"
    },
    {
      "id": 18,
      "code": "AS",
      "description": "Alaska Airlines"
    },
    {
      "id": 519,
      "code": "KO",
      "description": "Alaska Central Express"
    },
    {
      "id": 477,
      "code": "J5",
      "description": "Alaska Seaplane"
    },
    {
      "id": 30,
      "code": "YZ",
      "description": "ALAS URUGUAY"
    },
    {
      "id": 324,
      "code": "C9",
      "description": "Alphaland Aviation"
    },
    {
      "id": 286,
      "code": "A7",
      "description": "Calafia Airlines"
    },
    {
      "id": 330,
      "code": "CE",
      "description": "Chalair"
    },
    {
      "id": 521,
      "code": "L3",
      "description": "DHL de Guatemala"
    }
  ],
  "timestamp": null
}````
```

答:
Passed description as a sorting column and create pageRequest as follows. And description parameter and pageRequest send to findByDescriptionStartsWith method in AirlineRepository

```<code>PageRequest pageRequest = PageRequest
                .of((int) Math.ceil((float) (start / pageDataSize)), pageDataSize, Sort.by('description').ascending());

List<Airline> findByDescriptionStartsWith(String description, Pageable pageable);
</code>```

Body:
I'm writing a Spring Boot API endpoint and I need to return a list of Airlines ordered by a String (description) of 3 or more chars, the List must be sorted with the results that match the String at the beginning of the word at the top and the rest by alphabetical order

Airline class:

@Getter
@Setter
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "airline")
public class Airline implements Serializable {
    private static final long serialVersionUID = -5962418077659300886L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @Column
    private String code;

    @Column
    private String description;
}

I get the list that matches the String but I cannot get the order right

AirlineRepository

public interface AirlineRepository extends JpaRepository<Airline, Integer> {
    Airline getById(Integer id);

    List<Airline> findByDescriptionContainingIgnoreCase(String description, Pageable pageable);
    List<Airline> findByDescriptionStartsWithIgnoreCase(String description, Pageable pageable);
}

If I search the keyword 'ala' all airlines whose name starts with 'ala' should come first.

This is what I get

{
  "status": "SUCCESS",
  "message": "Execution Successful",
  "totalCount": 10,
  "content": [
    {
      "id": 962,
      "code": "6T",
      "description": "Air Mandalay"
    },
    {
      "id": 46,
      "code": "NZ",
      "description": "Air New Zealand"
    },
    {
      "id": 18,
      "code": "AS",
      "description": "Alaska Airlines"
    },
    {
      "id": 519,
      "code": "KO",
      "description": "Alaska Central Express"
    },
    {
      "id": 477,
      "code": "J5",
      "description": "Alaska Seaplane"
    },
    {
      "id": 30,
      "code": "YZ",
      "description": "ALAS URUGUAY"
    },
    {
      "id": 324,
      "code": "C9",
      "description": "Alphaland Aviation"
    },
    {
      "id": 286,
      "code": "A7",
      "description": "Calafia Airlines"
    },
    {
      "id": 330,
      "code": "CE",
      "description": "Chalair"
    },
    {
      "id": 521,
      "code": "L3",
      "description": "DHL de Guatemala"
    }
  ],
  "timestamp": null
}````

Body:
Passed description as a sorting column and create pageRequest as follows. And description parameter and pageRequest send to findByDescriptionStartsWith method in AirlineRepository

PageRequest pageRequest = PageRequest
                .of((int) Math.ceil((float) (start / pageDataSize)), pageDataSize, Sort.by('description').ascending());

List<Airline> findByDescriptionStartsWith(String description, Pageable pageable);


问:
Inject all Kafka Consumers created by a ConcurrentMessageListenerContainer in Spring Boot?
We are using the ConcurrentMessageListenerContainer to create our Kafka Consumers.

With the ConcurrentMessageListenerContainer#concurrency property it is possible to create multiple consumers.

Is it possible in a Spring Boot application to inject all Consumers created by the ConcurrentMessageListenerContainer? Or is it possible to obtain them somehow after an ApplicationEvent?

答:
Why do you need access to the underlying Consumer objects? They are managed by the container.

The consumer is available as a parameter in the message listener and is included in published events, but using the Consumer API directly is not recommended because such usage might conflict with the container's expectations.

It's ok to use passive APIs, such as getting the end offsets of subscribed topics.


问:
Gitlab autodeploy has stopped working, "no matching host key type found" error in server logs
I have .gitlab-ci.yml:

```<code>image: php:latest
deploy:
  stage: deploy
  only:
    - master
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_KEY" | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - ssh-keyscan $SSH_HOST > ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    - ssh $SSH_USER@$SSH_HOST "cd $SSH_PATH && git pull origin master"
</code>```

It worked for several months, but stopped working about a week ago, despite there was no changes on the server.

Pipeline failed job log:

```<code># mydomainproject.com:22 SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.5
$ chmod 644 ~/.ssh/known_hosts
$ ssh $SSH_USER@$SSH_HOST "cd $SSH_PATH && git pull origin master"
ssh: connect to host mydomainproject.com port 22: Connection refused
Cleaning up file based variables
ERROR: Job failed: exit code 1
</code>```

/var/log/auth.log on the server:

```<code>sshd[23927]: Connection closed by 35.227.7.98 port 50036 [preauth]
sshd[23925]: Connection closed by 35.227.7.98 port 50038 [preauth]
sshd[23924]: Connection closed by 35.227.7.98 port 50040 [preauth]
sshd[23928]: Unable to negotiate with 35.227.7.98 port 50042: no matching host key type found. Their offer: sk-ecdsa-sha2-nistp256@openssh.com [preauth]
sshd[23926]: Unable to negotiate with 35.227.7.98 port 50044: no matching host key type found. Their offer: sk-ssh-ed25519@openssh.com [preauth]
</code>```

I've read this and tried to edit .gitlab-ci.yml:

```<code>script:
    - ssh -oHostKeyAlgorithms=+sk-ecdsa-sha2-nistp256@openssh.com $SSH_USER@$SSH_HOST "cd $SSH_PATH && git pull origin master"
</code>```

It didn't help, result is the same.

I don't understand what's wrong and why it stopped working.

答: If anyone else has this problem, for me it helped to manually specify the host key instead of trying to let the gitlab runner determine it on the fly with ssh-keyscan.</p>

Body:
I have .gitlab-ci.yml:

image: php:latest
deploy:
  stage: deploy
  only:
    - master
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_KEY" | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - ssh-keyscan $SSH_HOST > ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    - ssh $SSH_USER@$SSH_HOST "cd $SSH_PATH && git pull origin master"

It worked for several months, but stopped working about a week ago, despite there was no changes on the server.

Pipeline failed job log:

# mydomainproject.com:22 SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.5
$ chmod 644 ~/.ssh/known_hosts
$ ssh $SSH_USER@$SSH_HOST "cd $SSH_PATH && git pull origin master"
ssh: connect to host mydomainproject.com port 22: Connection refused
Cleaning up file based variables
ERROR: Job failed: exit code 1

/var/log/auth.log on the server:

sshd[23927]: Connection closed by 35.227.7.98 port 50036 [preauth]
sshd[23925]: Connection closed by 35.227.7.98 port 50038 [preauth]
sshd[23924]: Connection closed by 35.227.7.98 port 50040 [preauth]
sshd[23928]: Unable to negotiate with 35.227.7.98 port 50042: no matching host key type found. Their offer: sk-ecdsa-sha2-nistp256@openssh.com [preauth]
sshd[23926]: Unable to negotiate with 35.227.7.98 port 50044: no matching host key type found. Their offer: sk-ssh-ed25519@openssh.com [preauth]

I've read this and tried to edit .gitlab-ci.yml:

script:
    - ssh -oHostKeyAlgorithms=+sk-ecdsa-sha2-nistp256@openssh.com $SSH_USER@$SSH_HOST "cd $SSH_PATH && git pull origin master"

It didn't help, result is the same.

I don't understand what's wrong and why it stopped working.


问:
Compute random number over certain time interval with Python
I did some research before posting but seem to be at a lost (not too experienced in coding).

I am attempting to generate or compute a random number for certain time interval with Python. I'm not looking for full code, I want help using the time library if that is the correct one to use.

Pseudo-code:

Allow python [PC] to compute a random number for 3 seconds

           ------> Store the computed generation in a value (i can handle this)

I would then use the random generated value to link access a python list (which would be automatically generated via a random number generation as well but i can figure that out).

答: Note: The function time.clock() has been removed, after having been deprecated since Python 3.3: use time.perf_counter() or time.process_time() instead, depending on your requirements, to have well-defined behavior. (Contributed by Matthias Bussonnier in bpo-36895.)</p>

ContentLicense: CC BY-SA 3.0


问:
In xCode, I'm getting the error "Loaded the nib but the view outlet was not set"?
I know there are multiple questions asking the same thing, but none of their solutions worked for me.

I made a custom viewController class (Home), and I made a .xib separately. (Effectively, I'll have 2 nibs -- one for the ipad version to load, and another for the iphone).

When I try to instantiate an instance of the home class, I got the error I mentioned in the question.

In the xib file, all I did was drag a viewcontroller object from the library to the screen, and it automatically added a viewcontroller icon below the file's owner and the first responder. I then went into the inspector of the viewController object and changed the class from viewController to Home.

The next step that I've discerned from the solutions is to connect the view outlet from the inspector. I'm not entirely sure what I'm supposed to be connecting it to. The solutions I've found say to connect it to the view icon, but again, all I see is files owner, first responder, and the vc object. It connects to none of them

Here is what I put in the app delegate

```<code>- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

 Home *homePage = [[Home alloc] initWithNibName:@"HomeIpad" bundle:nil];

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:homePage];
[self.window addSubview:navController.view];
[self.window makeKeyAndVisible];
return YES;
}
</code>```

答: You dont need to drag the view controller. Just drag a UIView instead and connect the File's owner View to this UIView.</p>

Body:
I know there are multiple questions asking the same thing, but none of their solutions worked for me.

I made a custom viewController class (Home), and I made a .xib separately. (Effectively, I'll have 2 nibs -- one for the ipad version to load, and another for the iphone).

When I try to instantiate an instance of the home class, I got the error I mentioned in the question.

In the xib file, all I did was drag a viewcontroller object from the library to the screen, and it automatically added a viewcontroller icon below the file's owner and the first responder. I then went into the inspector of the viewController object and changed the class from viewController to Home.

The next step that I've discerned from the solutions is to connect the view outlet from the inspector. I'm not entirely sure what I'm supposed to be connecting it to. The solutions I've found say to connect it to the view icon, but again, all I see is files owner, first responder, and the vc object. It connects to none of them

Here is what I put in the app delegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

 Home *homePage = [[Home alloc] initWithNibName:@"HomeIpad" bundle:nil];

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:homePage];
[self.window addSubview:navController.view];
[self.window makeKeyAndVisible];
return YES;
}


问:
How to render Positive, Negative differences as area between two lines in eCharts?
If we have two line charts, comparing say My Portfolio vs Overall Portfolio, the area between two lines need to be highlighted as green where My Portfolio is more than Overall portfolio, and red where it is less.

This is the kind of output that is expected -

var chartDom = document.getElementById('profileAumChart');
var myChart = echarts.init(chartDom);
var option;

option = {
title: {
    show: false
},
tooltip: {
    trigger: 'axis'
},
legend: {
    data: ['My Portfolio', 'Overall Portfolio']
},
grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
},
toolbox: {
    show: false
},
xAxis: {
    type: 'category',
    boundaryGap: false,
    data: ['Jan-21','Feb-21','Mar-21','Apr-21','May-21', 'Jun-21', 'Jul-21', 'Aug-21', 'Sep-21', 'Oct-21', 'Nov-21', 'Dec-21']
},
yAxis: {
    type: 'value'
},
series: [
    {
        name: 'My Portfolio',
        type: 'line',
        areaStyle: {
            color: 'green',
            //opacity: 1,
        },

        data: [150100,175965,185385,201384,206279,235905,238021,239323,245282,247671,255447,275911],
    },
    {

        name: 'Overall Portfolio',
        type: 'line',
        areaStyle: {
            color:'red',

            //opacity:1
        },

        data: [155066,165142,190811,192906,231941,250216,270047,288033,291842,308232,320941,334013],
    }
]
};

option && myChart.setOption(option);```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdn.jsdelivr.net/npm/echarts@5.3.0/dist/echarts.min.js"></script>
<div id="profileAumChart" style="width:100%; height:270px;"></div></code>```

答:
I was able to replicate the effect with an hack. I added a hidden series which has the lowest of the two series, and use the attribute "areastyle" and their sub-attribute color and opacity along with z-index and I am able to show such region.

I am still looking for an elegant solution and in case someone post it would really appreciate it.

I am sharing my code which can help someone who intend to have similar effects using e-charts.

Thanks.

var chartDom = document.getElementById('profileMonthlyNetSales');
            var myChart = echarts.init(chartDom);
            var option;

            option = {
            title: {
                show: false
            },
            tooltip: {
                trigger: 'axis'
            },
            legend: {
                data: ['My Portfolio', 'Overall Portfolio'],
                left: 'left'
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            toolbox: {
                show: false
            },
            xAxis: {
                type: 'category',
                boundaryGap: false,
                axisLabel:{
                    margin: 20,
                },
                data: ['Jan-21','Feb-21','Mar-21','Apr-21','May-21', 'Jun-21', 'Jul-21', 'Aug-21', 'Sep-21', 'Oct-21', 'Nov-21', 'Dec-21']
            },
            yAxis: [{
                type: 'value',
                min: -15000,
                offset: 10,
                axisLabel: {
                    //formatter: '${value}M'
                    formatter: function (value, index) {
                        return '$' + (value/1000) + 'k';
                    }
                }
            }
            ],
            series: [
                {
                    z:-1,
                    name: 'My Portfolio',
                    type: 'line',

                    areaStyle: {
                        color: 'green',
                        opacity:0.25,
                        origin: "start",

                    },
                    symbolSize: 5,
                    emphasis:{
                        disabled:true
                    },
                    data: [-6000,-1000,-7500,-7500,15300,16000,4900,5000,800, -9800, -10000, -9000],
                },
                {
                    z:-1,
                    name: 'Overall Portfolio',
                    type: 'line',
                    color: "#808080",
                    areaStyle: {
                        color:'red',
                        opacity: 0.25,
                        origin: "start",
                    },
                    symbolSize: 5,
                    emphasis:{
                        disabled:true
                    },
                    data: [-3000,-4000,-3700,-5000,15000,14800,5000,10200,5000,-9800,-1000,-8000],
                },
                {
                    z:-1,
                    name: 'Overall Portfolio1',
                    tooltip: {
                        show: false
                    },
                    type: 'line',
                    areaStyle: {
                        color:"white",
                        opacity:1.0,
                        origin: "start",
                    },
                    lineStyle: {
                        opacity: 0,
                    },
                    emphasis:{
                        disabled:true
                    },
                    symbolSize: 0,
                    data: [-6000,-4000,-7500,-7500,15000,14800,4900,5000,800,-9800,-10000,-9000],
                }
            ],

            };

            option && myChart.setOption(option);```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdn.jsdelivr.net/npm/echarts@5.3.0/dist/echarts.min.js"></script>
<div id="profileMonthlyNetSales" style="width:100%; height:270px;"></div></code>```

Body:
I was able to replicate the effect with an hack. I added a hidden series which has the lowest of the two series, and use the attribute "areastyle" and their sub-attribute color and opacity along with z-index and I am able to show such region.

I am still looking for an elegant solution and in case someone post it would really appreciate it.

I am sharing my code which can help someone who intend to have similar effects using e-charts.

Thanks.

var chartDom = document.getElementById('profileMonthlyNetSales');
            var myChart = echarts.init(chartDom);
            var option;

            option = {
            title: {
                show: false
            },
            tooltip: {
                trigger: 'axis'
            },
            legend: {
                data: ['My Portfolio', 'Overall Portfolio'],
                left: 'left'
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            toolbox: {
                show: false
            },
            xAxis: {
                type: 'category',
                boundaryGap: false,
                axisLabel:{
                    margin: 20,
                },
                data: ['Jan-21','Feb-21','Mar-21','Apr-21','May-21', 'Jun-21', 'Jul-21', 'Aug-21', 'Sep-21', 'Oct-21', 'Nov-21', 'Dec-21']
            },
            yAxis: [{
                type: 'value',
                min: -15000,
                offset: 10,
                axisLabel: {
                    //formatter: '${value}M'
                    formatter: function (value, index) {
                        return '$' + (value/1000) + 'k';
                    }
                }
            }
            ],
            series: [
                {
                    z:-1,
                    name: 'My Portfolio',
                    type: 'line',

                    areaStyle: {
                        color: 'green',
                        opacity:0.25,
                        origin: "start",

                    },
                    symbolSize: 5,
                    emphasis:{
                        disabled:true
                    },
                    data: [-6000,-1000,-7500,-7500,15300,16000,4900,5000,800, -9800, -10000, -9000],
                },
                {
                    z:-1,
                    name: 'Overall Portfolio',
                    type: 'line',
                    color: "#808080",
                    areaStyle: {
                        color:'red',
                        opacity: 0.25,
                        origin: "start",
                    },
                    symbolSize: 5,
                    emphasis:{
                        disabled:true
                    },
                    data: [-3000,-4000,-3700,-5000,15000,14800,5000,10200,5000,-9800,-1000,-8000],
                },
                {
                    z:-1,
                    name: 'Overall Portfolio1',
                    tooltip: {
                        show: false
                    },
                    type: 'line',
                    areaStyle: {
                        color:"white",
                        opacity:1.0,
                        origin: "start",
                    },
                    lineStyle: {
                        opacity: 0,
                    },
                    emphasis:{
                        disabled:true
                    },
                    symbolSize: 0,
                    data: [-6000,-4000,-7500,-7500,15000,14800,4900,5000,800,-9800,-10000,-9000],
                }
            ],

            };

            option && myChart.setOption(option);

<script src="https://cdn.jsdelivr.net/npm/echarts@5.3.0/dist/echarts.min.js"></script>
<div id="profileMonthlyNetSales" style="width:100%; height:270px;"></div>


问:
How to derive the equation for a non-linear time series regression model built in R?
I've built a non-linear time series regression model in R that I would like to write down as an equation, so that I can back-test against my data in an Excel spreadsheet. I've created a .ts object and created a model using the tslm function, as shown below:

```<code>model16 <- tslm(production ~ date + I(date^2) + I(date^3) +
                   I(temp_neg_32^3) +
                   I(humidity_avg^3) +
                   I(dew_avg^3) +
                  below_freezing_min,
                data = production_temp_no_outlier.ts)
</code>```

I find the coefficients for each variable in the model by using the following code:

```<code>summary(model16)
</code>```

The output is below:

So, my understanding is that the equation of my model should be:

```<code>y = -7924000000 + 1268000*date -67.62*(date^2) + 0.001202*(date^3) +
0.04395*(temp_neg_32^3) + 0.008658*(humidity_avg^3) -0.03762*(dew_avg^3) + -11930*below_freezing_min
</code>```

However, whenever I plug the data into this equation, the output is just completely off - it has nothing in common with the fitted curve visualization that I build in R based on this model. So I am clearly doing something wrong. I will be very grateful if someone could help point out my errors!

答:
This use of regression doesn't give you an exact fit, it gives you the line of best fit. What is the coefficient of determination? (AKA explained variance or R^2)

Take a look at this set of data (somewhat modeled after your example).

```<code>library(forecast)
library(tidyverse)

data("us_change", package = "fpp3")

fit <-  tslm(Production~Savings + I(Savings^2) + I(Savings^3) + I(Income^3) + Unemployment,
             data = ts(us_change))
summary(fit)
</code>```

Here I extracted the coefficients, so I can show you a bit more of what I mean. Then I created a function that calculates the outcome of the regression equation.

```<code>cFit <- coefficients(fit)
#   (Intercept)       Savings  I(Savings^2)  I(Savings^3)   I(Income^3)  Unemployment
#  5.221684e-01  6.321979e-03 -2.472784e-04 -6.376422e-06  7.029079e-03 -3.144743e+00

regFun <- function(cFit, data){
  attach(data)
  f = cFit[[2]] * Savings + cFit[[3]] * Savings^2 + cFit[[4]] * Savings^3 + cFit[[5]] * Income^3 + Unemployment + cFit[[1]]
  detach(data)
  return(f)
}
</code>```

Here are some examples of the predicted outcome versus the actual outcome.

```<code>fitOne <- regFun(cFit, us_change[1,])
# [1] 1.455793

us_change[1,]$Production
# [1] -2.452486

fitTwo <- regFun(cFit, us_change[2,])
# [1] 1.066338

us_change[2,]$Production
# [1] -0.5514595

fitThree <- regFun(cFit, us_change[3,])
# [1] 1.08083

us_change[3,]$Production
# [1] -0.3586518
</code>```

You can tell from the variance here that the production volume is not explained very well by the inputs I provided.

Now look at what happens when I graph this:

```<code>plt <- ggplot(data = us_change %>%
                mutate(Regression = regFun(cFit, us_change)),
       aes(x = Production)) +
  geom_point(aes(y = Savings, color = "Savings")) +
  geom_point(aes(y = Savings^2, color = "Savings^2")) +
  geom_point(aes(y = Savings^3, color = "Savings^3")) +
  geom_point(aes(y = Savings^3, color = "Savings^3")) +
  geom_point(aes(y = Unemployment, color = "Unemployment")) +
  geom_line(aes(y = Regression, color = "Regression")) +  # regression line
  scale_color_viridis_d(end = .8) + theme_bw()

plotly::ggplotly(plt)
</code>```

The regression equation output is the black line. It's the best fit, but there are values that are not represented all that well.

If you look closer, it's not a straight line either.

Body:
I've built a non-linear time series regression model in R that I would like to write down as an equation, so that I can back-test against my data in an Excel spreadsheet. I've created a .ts object and created a model using the tslm function, as shown below:

model16 <- tslm(production ~ date + I(date^2) + I(date^3) +
                   I(temp_neg_32^3) +
                   I(humidity_avg^3) +
                   I(dew_avg^3) +
                  below_freezing_min,
                data = production_temp_no_outlier.ts)

I find the coefficients for each variable in the model by using the following code:

summary(model16)

The output is below:

So, my understanding is that the equation of my model should be:

y = -7924000000 + 1268000*date -67.62*(date^2) + 0.001202*(date^3) +
0.04395*(temp_neg_32^3) + 0.008658*(humidity_avg^3) -0.03762*(dew_avg^3) + -11930*below_freezing_min

However, whenever I plug the data into this equation, the output is just completely off - it has nothing in common with the fitted curve visualization that I build in R based on this model. So I am clearly doing something wrong. I will be very grateful if someone could help point out my errors!

Body:
This use of regression doesn't give you an exact fit, it gives you the line of best fit. What is the coefficient of determination? (AKA explained variance or R^2)

Take a look at this set of data (somewhat modeled after your example).

library(forecast)
library(tidyverse)

data("us_change", package = "fpp3")

fit <-  tslm(Production~Savings + I(Savings^2) + I(Savings^3) + I(Income^3) + Unemployment,
             data = ts(us_change))
summary(fit)

Here I extracted the coefficients, so I can show you a bit more of what I mean. Then I created a function that calculates the outcome of the regression equation.

cFit <- coefficients(fit)
#   (Intercept)       Savings  I(Savings^2)  I(Savings^3)   I(Income^3)  Unemployment
#  5.221684e-01  6.321979e-03 -2.472784e-04 -6.376422e-06  7.029079e-03 -3.144743e+00

regFun <- function(cFit, data){
  attach(data)
  f = cFit[[2]] * Savings + cFit[[3]] * Savings^2 + cFit[[4]] * Savings^3 + cFit[[5]] * Income^3 + Unemployment + cFit[[1]]
  detach(data)
  return(f)
}

Here are some examples of the predicted outcome versus the actual outcome.

fitOne <- regFun(cFit, us_change[1,])
# [1] 1.455793

us_change[1,]$Production
# [1] -2.452486

fitTwo <- regFun(cFit, us_change[2,])
# [1] 1.066338

us_change[2,]$Production
# [1] -0.5514595

fitThree <- regFun(cFit, us_change[3,])
# [1] 1.08083

us_change[3,]$Production
# [1] -0.3586518

You can tell from the variance here that the production volume is not explained very well by the inputs I provided.

Now look at what happens when I graph this:

plt <- ggplot(data = us_change %>%
                mutate(Regression = regFun(cFit, us_change)),
       aes(x = Production)) +
  geom_point(aes(y = Savings, color = "Savings")) +
  geom_point(aes(y = Savings^2, color = "Savings^2")) +
  geom_point(aes(y = Savings^3, color = "Savings^3")) +
  geom_point(aes(y = Savings^3, color = "Savings^3")) +
  geom_point(aes(y = Unemployment, color = "Unemployment")) +
  geom_line(aes(y = Regression, color = "Regression")) +  # regression line
  scale_color_viridis_d(end = .8) + theme_bw()

plotly::ggplotly(plt)

The regression equation output is the black line. It's the best fit, but there are values that are not represented all that well.

If you look closer, it's not a straight line either.


问:
Move constructors and multiple inheritance

Synopsis

How can I safely design a move constructor when a class uses multiple inheritance?

Details

Consider the following scenario:

```<code>struct T { };
struct U { };

struct X : public T, public U
{
    X(X&& other)
      : T(std::move(other))
      , U(std::move(other)) // already moved?!
    {
    }
};
</code>```

Is there a way to move-construct both T and U safely?

答:
Can I use other object in sidetone constructor body after using moving it  like:</p>
```<code>struct T { };
struct U { };

struct X : public T, public U
{
    X(X&& other)
      : T(std::move(other))
      , U(std::move(other)) // already moved?!
    {
    member1 = other.member1; //something like.

    }
};
</code>```

Body:
Synopsis

How can I safely design a move constructor when a class uses multiple inheritance?

Details

Consider the following scenario:

struct T { };
struct U { };

struct X : public T, public U
{
    X(X&& other)
      : T(std::move(other))
      , U(std::move(other)) // already moved?!
    {
    }
};

Is there a way to move-construct both T and U safely?

Body:
Can I use other object in sidetone constructor body after using moving it  like:

struct T { };
struct U { };

struct X : public T, public U
{
    X(X&& other)
      : T(std::move(other))
      , U(std::move(other)) // already moved?!
    {
    member1 = other.member1; //something like.

    }
};


Title: replacing specific columns values in 2d array numpy

Body:
how to replace 4th and 5th column values in utl by new_values array and keep the remaining columns as it is

utl = np.array([[  3.  , 134.4 , 17.  ,   135.05 ,    22. ,   135.25 ,   0.04     ],
                [ 12.  , 134.3 , 17.  ,   135.05 ,    22. ,  135.8  ,    0.15     ]])

new_values=np.array([[ 27.,   135.45],
                     [ 27.,   136.55]])

i tried this but it does not work

# utl[:,[4,5]] = new_values
# utl[:,4] = new_values[:,0]

output must be

                                      #values changed
[[  3.  , 134.4 , 17.  ,   135.05 ,  |  27. ,  135.45  |,   0.04     ],
 [ 12.  , 134.3 , 17.  ,   135.05 ,  |  27. ,  136.55  |,    0.15     ]])

Body:
this works fine, as expected:

utl[:, [4,5]] = new_values

output:

array([[  3.  , 134.4 ,  17.  , 135.05,  27.  , 135.45,   0.04],
       [ 12.  , 134.3 ,  17.  , 135.05,  27.  , 136.55,   0.15]])