问:
Submenu closes improperly in React + Material UI
I have a nested menu structure like follows:

```<code> menuItems = [
  {
    "key": "key1",
    "caption": "Text1"
  },
  {
    "key": "key2",
    "caption": "Text2",
    "subMenuItems": [
      {
        "key": "key3",
        "caption": "Text3",
        "subMenuItems": [
          {
            "key": "key4",
            "caption": "Text4"
          }
        ]
      },
      {
        "key": "key5",
        "caption": "Text5",
        "subMenuItems": []
      },
      {
        "key": "key6",
        "caption": "Text6"
      }
    ]
  },
  {
    "key": "key7",
    "caption": "Text7"
  }
]
</code>```

And I want to open submenu items in a submenu that opens to right side of its parent. Something similar to Angular Material Menu (Nested menu example).

I tried using Material UI Menu, and it opens the menu as needed (See here), but has the following 2 issues:

If you open the parent menu and then any of the child menu, you will need to click outside as many times as the menus. Instead, it should close all the parent + child menus on clicking outside.

If you want to switch the child menu by clicking another parent menu item, you will need to first click on the parent menu (or as per issue-1, click outside) to close the currently open child menu and then click the desired parent menu item to open corresponding child menu.

Issue 1 can be addressed using ClickAwayListener as implemented here, but then it closes all menus even when trying to switch to another child menu, like switching from "Button 3" submenu to "More Items".

Thanks.

答:
Let's build a drawer/navbar which receives a list of items objects and render then in a recursive way. First thing first, define the structure like you already did in menuItems, i'll change it a little bit:

```<code>const items = [
     {name: 'Shallow Item', path='/', type:'shallow'},
     {
         name: 'Nested',
         type: 'nested',
         items:[
             {name: 'Shallow again', path='/nestedpath'}
         ]
     }
]
</code>```

Now we have two items in your list, one is a plain shallow item, which does not contain nested options, the second is a nested item which contains a list of shallow items inside it.

Now we have to build or two core components: <NestedItem> and <ShallowItem>. They should look something like this:

```<code>const ShallowItem = ({item, onClick}) =>(
    <ListItem
        component={Link}
        to={item.path || #}
        onClick={onClick ? onClick : ()=>{} }
    >
        <ListItemText primary={item.name}/>
        {Boolean(nested) &&
            <Icon>
                {collapsed ? 'arrow_drop_up' : 'arrow_drop_down'}
            </Icon>
        }
    </ListItem>
)
</code>```

Notice that onClick and to(react-router link) properties had their values attributed conditionally, because we're going to use the same component to render the first layer and the list of the NestedItem, like this:

```<code>const NestedItem = ({ item }) => {
    const [collapsed, toggler] = useState(false)
    const classes = useStyles()
    return (
        <div>
            <ShallowItem
                item={{ icon: item.icon, title: item.title }}
                nested
                collapsed={collapsed}
                onClick={() => toggler(!collapsed)}
            />
            <Collapse in={collapsed}>
                <List component='div'>
                    {item.items.map(item => (
                        <ShallowItem item={item} key={item.title}/>
                    ))}
                </List>
            </Collapse>

        </div>

)}
</code>```

There we go, did you grabbed the ideia? The only component really getting rendered is ShallowItem cause NestedItem is just a collection of shallow items. So we first render a shallow item that opens a collapse container containing a sublist of more shallow items.The only thing that we need to do now is check if the item have subitems, case positive render a NestedItem otherwise render ShallowItem. That function is:

```<code>const renderItems = items =>{
    for(let item of items){
        switch(item.type){
            case 'nested': return <NestedItem item={item} />

            case 'shallow' : return <ShallowItem item={item} />
        }
    }
}
</code>```

Now you have a recursive way to render nested items, you only need to stylize one component, and make the depth deeper is pretty easy now. We use this solution in our company and it works like charm.

Body:
I have a nested menu structure like follows:

 menuItems = [
  {
    "key": "key1",
    "caption": "Text1"
  },
  {
    "key": "key2",
    "caption": "Text2",
    "subMenuItems": [
      {
        "key": "key3",
        "caption": "Text3",
        "subMenuItems": [
          {
            "key": "key4",
            "caption": "Text4"
          }
        ]
      },
      {
        "key": "key5",
        "caption": "Text5",
        "subMenuItems": []
      },
      {
        "key": "key6",
        "caption": "Text6"
      }
    ]
  },
  {
    "key": "key7",
    "caption": "Text7"
  }
]

And I want to open submenu items in a submenu that opens to right side of its parent. Something similar to Angular Material Menu (Nested menu example).

I tried using Material UI Menu, and it opens the menu as needed (See here), but has the following 2 issues:

If you open the parent menu and then any of the child menu, you will need to click outside as many times as the menus. Instead, it should close all the parent + child menus on clicking outside.

If you want to switch the child menu by clicking another parent menu item, you will need to first click on the parent menu (or as per issue-1, click outside) to close the currently open child menu and then click the desired parent menu item to open corresponding child menu.

Issue 1 can be addressed using ClickAwayListener as implemented here, but then it closes all menus even when trying to switch to another child menu, like switching from "Button 3" submenu to "More Items".

Thanks.

Body:
Let's build a drawer/navbar which receives a list of items objects and render then in a recursive way. First thing first, define the structure like you already did in menuItems, i'll change it a little bit:

const items = [
     {name: 'Shallow Item', path='/', type:'shallow'},
     {
         name: 'Nested',
         type: 'nested',
         items:[
             {name: 'Shallow again', path='/nestedpath'}
         ]
     }
]

Now we have two items in your list, one is a plain shallow item, which does not contain nested options, the second is a nested item which contains a list of shallow items inside it.

Now we have to build or two core components: <NestedItem> and <ShallowItem>. They should look something like this:

const ShallowItem = ({item, onClick}) =>(
    <ListItem
        component={Link}
        to={item.path || #}
        onClick={onClick ? onClick : ()=>{} }
    >
        <ListItemText primary={item.name}/>
        {Boolean(nested) &&
            <Icon>
                {collapsed ? 'arrow_drop_up' : 'arrow_drop_down'}
            </Icon>
        }
    </ListItem>
)

Notice that onClick and to(react-router link) properties had their values attributed conditionally, because we're going to use the same component to render the first layer and the list of the NestedItem, like this:

const NestedItem = ({ item }) => {
    const [collapsed, toggler] = useState(false)
    const classes = useStyles()
    return (
        <div>
            <ShallowItem
                item={{ icon: item.icon, title: item.title }}
                nested
                collapsed={collapsed}
                onClick={() => toggler(!collapsed)}
            />
            <Collapse in={collapsed}>
                <List component='div'>
                    {item.items.map(item => (
                        <ShallowItem item={item} key={item.title}/>
                    ))}
                </List>
            </Collapse>

        </div>

)}

There we go, did you grabbed the ideia? The only component really getting rendered is ShallowItem cause NestedItem is just a collection of shallow items. So we first render a shallow item that opens a collapse container containing a sublist of more shallow items.The only thing that we need to do now is check if the item have subitems, case positive render a NestedItem otherwise render ShallowItem. That function is:

const renderItems = items =>{
    for(let item of items){
        switch(item.type){
            case 'nested': return <NestedItem item={item} />

            case 'shallow' : return <ShallowItem item={item} />
        }
    }
}

Now you have a recursive way to render nested items, you only need to stylize one component, and make the depth deeper is pretty easy now. We use this solution in our company and it works like charm.


来源: stackexchange

问:
Hosting angular and able to view on all PC
I have hosted my angular application using ng serve --host IP_Address. Since I have remotely accessed the PC from my virtual machine, I am able to ping to that machine and also I can open the virtual machine browser and open the application. However, I am not able to access the application from my Windows machine. How can I solve this?</p>

答:
If you want to be able to access your development server from other machines use

```<code>ng serve --host=0.0.0.0
</code>```

You can also set this configuration in your angular.json:

```<code>    ...
    "serve": {
      "builder": "@angular-devkit/build-angular:dev-server",
      "options": {
        "browserTarget": "app:build",
        "host": "0.0.0.0"
    ...
</code>```

Doing so will cause the CLI to give you the warning below to remind you that it is not a secure server.

```<code>WARNING: This is a simple server for use in testing or debugging Angular applications
locally. It hasn't been reviewed for security issues.

Binding this server to an open connection can result in compromising your application or
computer. Using a different host than the one passed to the "--host" flag might result in
websocket connection issues. You might need to use "--disableHostCheck" if that's the
case.
</code>```

ContentLicense: CC BY-SA 4.0

Body:
If you want to be able to access your development server from other machines use

ng serve --host=0.0.0.0

You can also set this configuration in your angular.json:

    ...
    "serve": {
      "builder": "@angular-devkit/build-angular:dev-server",
      "options": {
        "browserTarget": "app:build",
        "host": "0.0.0.0"
    ...

Doing so will cause the CLI to give you the warning below to remind you that it is not a secure server.

WARNING: This is a simple server for use in testing or debugging Angular applications
locally. It hasn't been reviewed for security issues.

Binding this server to an open connection can result in compromising your application or
computer. Using a different host than the one passed to the "--host" flag might result in
websocket connection issues. You might need to use "--disableHostCheck" if that's the
case.


问:
Divide numbers in SQL
I have a database with orders of products and i need to divide the orders for men with the all orders for every year.

I successfully printed the all orders for every year and the mens orders for every year but I don't have an idea how to show a number that divide the numbers.

```<code>SELECT
    YEAR(o.Order_Date) AS year,
    COUNT(o.order_id) AS number_of_orders
FROM
    [targil 2].[dbo].[exc2 - product] p, [targil 2].[dbo].[exc2 - orders] o
WHERE
    p.Product_ID = o.Product_ID
GROUP BY
    YEAR(o.Order_Date);
</code>```

Output =

```<code>   year    number_of_orders
   -------------------------
   2012        540
   2013        512
   2014        180

SELECT DISTCINT
    YEAR(o.Order_Date) AS year,
    COUNT(o.order_id) AS number_of_orders
FROM
    [targil 2].[dbo].[exc2 - product] p, [targil 2].[dbo].[exc2 - orders] o
WHERE
    p.Product_ID = o.Product_ID
    AND p.Product_Name LIKE '%men%'
GROUP BY
    YEAR(o.Order_Date);
</code>```

Output

```<code>year  number_of_orders
----------------------
2012       50
2013      146
2014      138
</code>```

Desired output

```<code>year   number_of_men_orders_of_all_orders
----------------------------------------
2012        0.0925
2013        0.285
2014        0.766
</code>```

答:
Use conditional aggregation!  And learn to use proper, explicit, standard JOIN syntax

```<code>select year(o.Order_Date) as year,
       count(*) as number_of_orders,
       sum(case when p.Product_Name LIKE '%men%' then 1 else 0 end) as men_count,
       avg(case when p.Product_Name LIKE '%men%' then 1.0 else 0 end) as men_ratio,
from [targil 2].[dbo].[exc2 - product] p join
     [targil 2].[dbo].[exc2 - orders] o
      on p.Product_ID = o.Product_ID
group by year(o.Order_Date)
order by year(o.Order_date);
</code>```

Title: Divide numbers in SQL

Body:
I have a database with orders of products and i need to divide the orders for men with the all orders for every year.

I successfully printed the all orders for every year and the mens orders for every year but I don't have an idea how to show a number that divide the numbers.

SELECT
    YEAR(o.Order_Date) AS year,
    COUNT(o.order_id) AS number_of_orders
FROM
    [targil 2].[dbo].[exc2 - product] p, [targil 2].[dbo].[exc2 - orders] o
WHERE
    p.Product_ID = o.Product_ID
GROUP BY
    YEAR(o.Order_Date);

Output =

   year    number_of_orders
   -------------------------
   2012        540
   2013        512
   2014        180

SELECT DISTCINT
    YEAR(o.Order_Date) AS year,
    COUNT(o.order_id) AS number_of_orders
FROM
    [targil 2].[dbo].[exc2 - product] p, [targil 2].[dbo].[exc2 - orders] o
WHERE
    p.Product_ID = o.Product_ID
    AND p.Product_Name LIKE '%men%'
GROUP BY
    YEAR(o.Order_Date);

Output

year  number_of_orders
----------------------
2012       50
2013      146
2014      138

Desired output

year   number_of_men_orders_of_all_orders
----------------------------------------
2012        0.0925
2013        0.285
2014        0.766

Body:
Use conditional aggregation!  And learn to use proper, explicit, standard JOIN syntax

select year(o.Order_Date) as year,
       count(*) as number_of_orders,
       sum(case when p.Product_Name LIKE '%men%' then 1 else 0 end) as men_count,
       avg(case when p.Product_Name LIKE '%men%' then 1.0 else 0 end) as men_ratio,
from [targil 2].[dbo].[exc2 - product] p join
     [targil 2].[dbo].[exc2 - orders] o
      on p.Product_ID = o.Product_ID
group by year(o.Order_Date)
order by year(o.Order_date);


问:
Why does using *ngIf = "authService.getUser()" in my top level app component html break my login component?
I am new to Angular so please bear with my naivety. I created a login component, which I use to prevent access to router navigation links in the main app-component html until the user logs in. The login component itself is another routed page, and I wanted to instead add the login component to my mainpage, and hide the routing navigation links until the user logs in.

To hide the user navigation links in the app-component html I tried using
*ngIf="authService.getUser()".

*ngIf="authService.getUser()" hides the navigation components until the user is logged in as expected, but it unexpectedly also didn't render the entirety of the login component (the user and password fields and submit button), except the first text which simply says "LOGIN". So the user has no way to login.
this is app.component.html:

```<code>  <app-login>

  </app-login>

<div class="page-header" >
   <div class="container">

      <div *ngIf="authService.getUser()" class="navLinks">
        <a  [routerLink]="['/home']"> Home</a>
        <a [routerLink]="['/about']"> About App</a>

        <a [routerLink]="['/login']">Login</a>
        <a [routerLink]="['/protected']">Protected</a>
    </div>

  </div>
</div>

<div id="content">
  <div class="container">
   <router-outlet></router-outlet>
  </div>
</div>
</code>```

and these are my login component files

login.component.ts:

```<code>import { Component } from '@angular/core';
import { AuthService } from '../auth.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent {
  message: string;

  constructor(public authService: AuthService) {
    this.message = '';
  }

  login(username: string, password: string): boolean {
    this.message = '';
    if (!this.authService.login(username, password)) {
      this.message = 'Incorrect credentials.';
      setTimeout(function() {
        this.message = '';
      }.bind(this), 2500);
    }
    return false;
  }

  logout(): boolean {
    this.authService.logout();
    return false;
  }

}
</code>```

login.component.html:

```<code><h1>Login</h1>

<div class="alert alert-danger" role="alert" *ngIf="message">
  {{ message }}
</div>

<form class="form-inline" *ngIf="!authService.getUser()">
  <div class="form-group">
    <label for="username">User: (type <em>user</em>)</label>
    <input class="form-control" name="username" #username>
  </div>

  <div class="form-group">
    <label for="password">Password: (type <em>password</em>)</label>
    <input class="form-control" type="password" name="password" #password>
  </div>

  <a class="btn btn-default" (click)="login(username.value, password.value)">
    Submit
  </a>
</form>

<div class="well" *ngIf="authService.getUser()">
  Logged in as <b>{{ authService.getUser() }}</b>
  <a href (click)="logout()">Log out</a>
</div>
</code>```

答: What is in your authService.getUser() method? If it is asynchronous all you have to do is *ngIf="(authService.getUser() | async)".

Body:
I am new to Angular so please bear with my naivety. I created a login component, which I use to prevent access to router navigation links in the main app-component html until the user logs in. The login component itself is another routed page, and I wanted to instead add the login component to my mainpage, and hide the routing navigation links until the user logs in.

To hide the user navigation links in the app-component html I tried using
*ngIf="authService.getUser()".

*ngIf="authService.getUser()" hides the navigation components until the user is logged in as expected, but it unexpectedly also didn't render the entirety of the login component (the user and password fields and submit button), except the first text which simply says "LOGIN". So the user has no way to login.
this is app.component.html:

  <app-login>

  </app-login>

         Home
         About App

        Login
        Protected

   <router-outlet></router-outlet>

and these are my login component files

login.component.ts:

import { Component } from '@angular/core';
import { AuthService } from '../auth.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent {
  message: string;

  constructor(public authService: AuthService) {
    this.message = '';
  }

  login(username: string, password: string): boolean {
    this.message = '';
    if (!this.authService.login(username, password)) {
      this.message = 'Incorrect credentials.';
      setTimeout(function() {
        this.message = '';
      }.bind(this), 2500);
    }
    return false;
  }

  logout(): boolean {
    this.authService.logout();
    return false;
  }

}

login.component.html:

Login

  {{ message }}

<form class="form-inline" *ngIf="!authService.getUser()">

    User: (type user)
    <input class="form-control" name="username" #username>

    Password: (type password)
    <input class="form-control" type="password" name="password" #password>

    Submit

</form>

  Logged in as {{ authService.getUser() }}
  Log out


问:
Unmarshal JAXB elements with same tag as in parent and child
I want to unmarshall the below XML using JAXB, so that I can navigate to child node to read the leaf tag element.

```<code><root>
   <concept name="GrandParent">
    <concept name="Parent1">
        <concept name="Child11">
            <input>some child input11</input>
        </concept>
        <concept name="Child12">
            <input>some child input21</input>
        </concept>
    </concept>
    <concept name="Parent2">
            <concept name="Child21">
                <input>some child input21</input>
            </concept>
            <concept name="Child22">
                 <input>some child input22</input>
            </concept>
    </concept>
   </concept>
</root>
</code>```

I would expect number of children for parent1 and parent 2.

答:
You need to build model, annotate with JAXB annotations and parse given XML. See below example:

```<code>import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.io.File;
import java.util.List;

public class XmlMapperApp {

    public static void main(String[] args) throws Exception {
        File xmlFile = new File("./resource/test.xml").getAbsoluteFile();

        JAXBContext jaxbContext = JAXBContext.newInstance(Roots.class);

        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        Concept root = ((Roots) unmarshaller.unmarshal(xmlFile)).getConcept();
        root.getConcept().forEach(System.out::println);
    }
}

@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
class Roots {

    private Concept concept;

    // getters, setters, toString
}

@XmlType(name = "concept")
@XmlAccessorType(XmlAccessType.FIELD)
class Concept {

    @XmlAttribute
    private String name;

    @XmlElement
    private List<Concept> concept;

    @XmlElement
    private String input;

    // getters, setters, toString
}
</code>```

Above code prints:

```<code>Concept{name='Parent1', concept=[Concept{name='Child11', concept=null, input='some child input11'}, Concept{name='Child12', concept=null, input='some child input21'}], input='null'}
Concept{name='Parent2', concept=[Concept{name='Child21', concept=null, input='some child input21'}, Concept{name='Child22', concept=null, input='some child input22'}], input='null'}
</code>```

Body:
I want to unmarshall the below XML using JAXB, so that I can navigate to child node to read the leaf tag element.

<root>
   <concept name="GrandParent">
    <concept name="Parent1">
        <concept name="Child11">
            <input>some child input11</input>
        </concept>
        <concept name="Child12">
            <input>some child input21</input>
        </concept>
    </concept>
    <concept name="Parent2">
            <concept name="Child21">
                <input>some child input21</input>
            </concept>
            <concept name="Child22">
                 <input>some child input22</input>
            </concept>
    </concept>
   </concept>
</root>

I would expect number of children for parent1 and parent 2.

Body:
You need to build model, annotate with JAXB annotations and parse given XML. See below example:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.io.File;
import java.util.List;

public class XmlMapperApp {

    public static void main(String[] args) throws Exception {
        File xmlFile = new File("./resource/test.xml").getAbsoluteFile();

        JAXBContext jaxbContext = JAXBContext.newInstance(Roots.class);

        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        Concept root = ((Roots) unmarshaller.unmarshal(xmlFile)).getConcept();
        root.getConcept().forEach(System.out::println);
    }
}

@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
class Roots {

    private Concept concept;

    // getters, setters, toString
}

@XmlType(name = "concept")
@XmlAccessorType(XmlAccessType.FIELD)
class Concept {

    @XmlAttribute
    private String name;

    @XmlElement
    private List<Concept> concept;

    @XmlElement
    private String input;

    // getters, setters, toString
}

Above code prints:

Concept{name='Parent1', concept=[Concept{name='Child11', concept=null, input='some child input11'}, Concept{name='Child12', concept=null, input='some child input21'}], input='null'}
Concept{name='Parent2', concept=[Concept{name='Child21', concept=null, input='some child input21'}, Concept{name='Child22', concept=null, input='some child input22'}], input='null'}


问:
dialogRef.afterClosed is not a function
Hi im doing unit testing and trying to get coverage for my subscription. However it keeps failing with the error dialogRef.afterClosed is not a function

Im not sure at what or how I can spy on the afterClosed() function, but thats the only part I cant seem to cover.
    ...

```<code>import { MatDialog } from '@angular/material/dialog';
....
constructor( private dialog: MatDialog) { }

showLogin(): void {

  const dialogRef = this.dialog.open(LoginDialogComponent, {
    width: '400px',
    height: 'auto',
    data: this.loginContext
  });

  dialogRef.afterClosed().subscribe(result => {
    if (this.loginContext.loggedIn) {
      this.showApply();
    }
  });
}
</code>```

this is the LoginDialogComponent

```<code> ....

 @Component({
   selector: 'app-login-dialog',
   templateUrl: './login-dialog.component.html',
   styleUrls: ['./login-dialog.component.scss']
 })
 export class LoginDialogComponent implements OnInit {

   constructor(
     private authService: AuthService,
     private alertService: AlertService,
     public dialogRef: MatDialogRef<LoginState>,
     @Inject(MAT_DIALOG_DATA) public data: LoginState) { }

   ngOnInit() {
     this.data.loggedIn = false;
   }

   login(loginEvent: LoginEvent): void {

     this.authService.login(loginData).then(
       resp => {
         this.data.loggedIn = true; // feedback
         this.dialogRef.close();
       },
       err => {
         this.alertService.showAlert(err);
       }
     );
   }

 }
</code>```

答:
I have taken Sam Tsai's answer one step further and created a stub file to be more concise. Here's the stub file contents:

```<code>import { of } from 'rxjs';

/*
  The default behavior is to test that the user clicked 'OK' in the dialog.
    To reset to this behavior (if you've previously tested 'Cancel'),
    call setResult(true).

  If you want to test that the user clicked 'Cancel' in the dialog,
    call setResult(false).
*/

export class MatDialogStub {
  result: boolean = true;

  setResult(val: boolean) {
    this.result = val;
  }

  open() {
    return {afterClosed: () => of(this.result) };
  }
}
</code>```

Then in the .spec.ts file you use the stub like this:

```<code>import { MatDialogStub } from '../../../../testing/mat-dialog-stub'; // <--- (import here)

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;
  const dialogStub = new MatDialogStub(); // <--- (declare here)

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [],
      declarations: [ MyComponent ],
      providers: [
        { provide: MatDialog,  useValue: dialogStub } // <--- (use here)
      ]
    })
      .compileComponents();
  }));
  //...
});
</code>```

And in the actual test you can set the return value to true or false to simulate clicking the 'OK' or 'Cancel' button respectively by calling the setResult() function:

```<code>dialogStub.setResult(true);
</code>```

or

```<code>dialogStub.setResult(false);
</code>```

Note: the default value for the stub tests 'OK' so you don't have to call the function if you are just testing 'OK'.

The tests below first simulate a 'Cancel' and then an 'OK' button click:

```<code>it(`should not call 'delete' when Submit button pressed and user cancels`, async(() => {
    component.apis = [new Api({name: 'abc'})];
    component.displayPermissions = [new Permission({name: 'abc'})];
    dialogStub.setResult(false); // <--- (call the function here)
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    compiled.querySelector('button').click();
    expect(permissionService.delete.calls.count()).toBe(0, 'no calls');
}));

it(`should call 'delete' once when Submit button pressed and not cancelled`, async(() => {
    component.apis = [new Api({name: 'abc'})];
    component.displayPermissions = [new Permission({name: 'abc'})];
    dialogStub.setResult(true); // <--- (call the function here)
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    compiled.querySelector('button').click();
    expect(permissionService.delete.calls.count()).toBe(1, 'one call');
}));
</code>```

Originial Answer

I have looked everywhere for a concise way to mock the MatDialog and get rid of the error I was getting dialogRef.afterClosed is not a function. (see some links I tried at bottom). Nothing I found was the right solution until I tried Sam Tsai's answer to this question. It was a simple solution that got rid of all my errors and enabled me to correctly test my application. I wish I found this before spending so much time on all the other links.

This is the unit test that was failing; it failed on the ('button').click event because it opens the MatDialog and only performs the delete if the dialog returns true. I didn't know how to mock the MatDialog correctly so the delete would happen:

```<code>it("should call 'delete' once when Submit button pressed and not cancelled", async(() => {
    component.apis = [new Api({name: 'abc'})];
    component.displayPermissions = [new Permission({name: 'abc'})];
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    compiled.querySelector('button').click();
    expect(permissionService.delete.calls.count()).toBe(1, 'one call');
}));
</code>```

I fixed it by adding this:

```<code>describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;

  const dialogRefStub = {
    afterClosed() {
      return of(true);
    }
  };

  const dialogStub = { open: () => dialogRefStub };

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [],
      declarations: [ MyComponent ],
      providers: [
        { provide: MatDialog,  useValue: dialogStub }
      ]
    })
      .compileComponents();
  }));
  //...
});
</code>```

Some links I tried:

Mocking Angular Material Dialog afterClosed() for unit test

How do I write simple test to check the behaviour of MatDialog in Angular 2?

Cannot read property 'afterClosed' of undefined when unit testing MatDialog in Jasmine

Failed: Can't resolve all parameters for MatDialogRef: (?, ?, ?). unit testing Angular project

How do I unit-test that MatDialog is closed, by mat-dialog-close or otherwise

Title: dialogRef.afterClosed is not a function

Body:
Hi im doing unit testing and trying to get coverage for my subscription. However it keeps failing with the error dialogRef.afterClosed is not a function

Im not sure at what or how I can spy on the afterClosed() function, but thats the only part I cant seem to cover.
    ...

import { MatDialog } from '@angular/material/dialog';
....
constructor( private dialog: MatDialog) { }

showLogin(): void {

  const dialogRef = this.dialog.open(LoginDialogComponent, {
    width: '400px',
    height: 'auto',
    data: this.loginContext
  });

  dialogRef.afterClosed().subscribe(result => {
    if (this.loginContext.loggedIn) {
      this.showApply();
    }
  });
}

this is the LoginDialogComponent

 ....

 @Component({
   selector: 'app-login-dialog',
   templateUrl: './login-dialog.component.html',
   styleUrls: ['./login-dialog.component.scss']
 })
 export class LoginDialogComponent implements OnInit {

   constructor(
     private authService: AuthService,
     private alertService: AlertService,
     public dialogRef: MatDialogRef<LoginState>,
     @Inject(MAT_DIALOG_DATA) public data: LoginState) { }

   ngOnInit() {
     this.data.loggedIn = false;
   }

   login(loginEvent: LoginEvent): void {

     this.authService.login(loginData).then(
       resp => {
         this.data.loggedIn = true; // feedback
         this.dialogRef.close();
       },
       err => {
         this.alertService.showAlert(err);
       }
     );
   }

 }

Body:
I have taken Sam Tsai's answer one step further and created a stub file to be more concise. Here's the stub file contents:

import { of } from 'rxjs';

/*
  The default behavior is to test that the user clicked 'OK' in the dialog.
    To reset to this behavior (if you've previously tested 'Cancel'),
    call setResult(true).

  If you want to test that the user clicked 'Cancel' in the dialog,
    call setResult(false).
*/

export class MatDialogStub {
  result: boolean = true;

  setResult(val: boolean) {
    this.result = val;
  }

  open() {
    return {afterClosed: () => of(this.result) };
  }
}

Then in the .spec.ts file you use the stub like this:

import { MatDialogStub } from '../../../../testing/mat-dialog-stub'; // <--- (import here)

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;
  const dialogStub = new MatDialogStub(); // <--- (declare here)

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [],
      declarations: [ MyComponent ],
      providers: [
        { provide: MatDialog,  useValue: dialogStub } // <--- (use here)
      ]
    })
      .compileComponents();
  }));
  //...
});

And in the actual test you can set the return value to true or false to simulate clicking the 'OK' or 'Cancel' button respectively by calling the setResult() function:

dialogStub.setResult(true);

or

dialogStub.setResult(false);

Note: the default value for the stub tests 'OK' so you don't have to call the function if you are just testing 'OK'.

The tests below first simulate a 'Cancel' and then an 'OK' button click:

it(`should not call 'delete' when Submit button pressed and user cancels`, async(() => {
    component.apis = [new Api({name: 'abc'})];
    component.displayPermissions = [new Permission({name: 'abc'})];
    dialogStub.setResult(false); // <--- (call the function here)
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    compiled.querySelector('button').click();
    expect(permissionService.delete.calls.count()).toBe(0, 'no calls');
}));

it(`should call 'delete' once when Submit button pressed and not cancelled`, async(() => {
    component.apis = [new Api({name: 'abc'})];
    component.displayPermissions = [new Permission({name: 'abc'})];
    dialogStub.setResult(true); // <--- (call the function here)
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    compiled.querySelector('button').click();
    expect(permissionService.delete.calls.count()).toBe(1, 'one call');
}));

Originial Answer

I have looked everywhere for a concise way to mock the MatDialog and get rid of the error I was getting dialogRef.afterClosed is not a function. (see some links I tried at bottom). Nothing I found was the right solution until I tried Sam Tsai's answer to this question. It was a simple solution that got rid of all my errors and enabled me to correctly test my application. I wish I found this before spending so much time on all the other links.

This is the unit test that was failing; it failed on the ('button').click event because it opens the MatDialog and only performs the delete if the dialog returns true. I didn't know how to mock the MatDialog correctly so the delete would happen:

it("should call 'delete' once when Submit button pressed and not cancelled", async(() => {
    component.apis = [new Api({name: 'abc'})];
    component.displayPermissions = [new Permission({name: 'abc'})];
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    compiled.querySelector('button').click();
    expect(permissionService.delete.calls.count()).toBe(1, 'one call');
}));

I fixed it by adding this:

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;

  const dialogRefStub = {
    afterClosed() {
      return of(true);
    }
  };

  const dialogStub = { open: () => dialogRefStub };

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [],
      declarations: [ MyComponent ],
      providers: [
        { provide: MatDialog,  useValue: dialogStub }
      ]
    })
      .compileComponents();
  }));
  //...
});

Some links I tried:

Mocking Angular Material Dialog afterClosed() for unit test

How do I write simple test to check the behaviour of MatDialog in Angular 2?

Cannot read property 'afterClosed' of undefined when unit testing MatDialog in Jasmine

Failed: Can't resolve all parameters for MatDialogRef: (?, ?, ?). unit testing Angular project

How do I unit-test that MatDialog is closed, by mat-dialog-close or otherwise


问:
How can we create a `TextIOWrapper` instance?
https://docs.python.org/3/library/io.html#overview says, we can create a TextIOBase instance by

```<code>f = open("myfile.txt", "r", encoding="utf-8")
</code>```

and a BufferedIOBase instance by

```<code>f = open("myfile.jpg", "rb")
</code>```

How can we create a TextIOWrapper instance? For example, can it be done by using open()?

答:
Per the docs (my emphasis):

The type of file object returned by the open() function depends on the mode. When open() is used to open a file in a text mode ('w', 'r', 'wt', 'rt', etc.), it returns a subclass of io.TextIOBase (specifically io.TextIOWrapper). When used to open a file in a binary mode with buffering, the returned class is a subclass of io.BufferedIOBase.

Indeed,
f = open("myfile.txt", "r", encoding="utf-8") returns a TextIOWrapper:

```<code>In [18]: f = open("data", "r", encoding="utf-8")

In [19]: type(f)
Out[19]: _io.TextIOWrapper

In [20]: type(f).mro()
Out[20]: [_io.TextIOWrapper, _io._TextIOBase, _io._IOBase, object]
</code>```

Body:
https://docs.python.org/3/library/io.html#overview says, we can create a TextIOBase instance by

f = open("myfile.txt", "r", encoding="utf-8")

and a BufferedIOBase instance by

f = open("myfile.jpg", "rb")

How can we create a TextIOWrapper instance? For example, can it be done by using open()?

Body:
Per the docs (my emphasis):

The type of file object returned by the open() function depends on the mode. When open() is used to open a file in a text mode ('w', 'r', 'wt', 'rt', etc.), it returns a subclass of io.TextIOBase (specifically io.TextIOWrapper). When used to open a file in a binary mode with buffering, the returned class is a subclass of io.BufferedIOBase.

Indeed,
f = open("myfile.txt", "r", encoding="utf-8") returns a TextIOWrapper:

In [18]: f = open("data", "r", encoding="utf-8")

In [19]: type(f)
Out[19]: _io.TextIOWrapper

In [20]: type(f).mro()
Out[20]: [_io.TextIOWrapper, _io._TextIOBase, _io._IOBase, object]


问:
How do the if-else statements in this function from a tutorial make any sense?
I'm going through this tutorial for a simple playlist with Vue.

I'm confused by the author's play() function, particularly the series of if-else statements. It appears to check whether index is a number, and if it is (and I can't imagine how it wouldn't be), it seems to skip the rest of the code that checks for whether the selected track is the same as the current track, among other things (link to the repo and function in question here):

```<code>play (index) {
  let selectedTrackIndex = this.playlist.findIndex(track => track === this.selectedTrack)

  if (typeof index === 'number') {
    index = index

  } else if (this.selectedTrack) {
    if (this.selectedTrack != this.currentTrack) {
      this.stop()
    }
    index = selectedTrackIndex
  } else {
    index = this.index
  }

  let track = this.playlist[index].howl

  if (track.playing()) {
    return
  } else {
    track.play()
  }

  this.selectedTrack = this.playlist[index]
  this.playing = true
  this.index = index
}
</code>```

The author's summary of the above code:

The method takes an index as the parameter, which specifies the track
  to be played. First, we get the index of the selected track. Then, we
  make some checks to determine the value of the index. If an index is
  provided as an argument and it's a number, then we use it. If a track
  is selected, we use the index of the selected track. If the selected
  track is different from the current one, we use the stop() method to
  stop the current one. Finally, if neither an index argument is passed
  nor a track is selected, we use the value of the index data property.

I checked MDN and a few other sources and didn't see anything special about an if() followed by an else if() in JavaScript. So I figure I have to be missing something here. Why is a validation check on index tied to checking whether the selected track is the same as the current track? The other checks inside the else if() and else blocks seem like stuff you wouldn't want to leave out, and yet his live demo of the app works. I asked the author to elaborate in the comments of the article but the article is almost a year old, so I'm not sure if he'll get back to me. Thanks to everyone in advance.

答:
It's not really a validation test, it's just detecting whether an argument was supplied or not. If the argument isn't supplied, or it's not a number, the function performs default behaviors.

If the caller uses track.play(2), they're specifically telling it to play track 2. The test if (typeof index == 'number') will succeed, and we'll use that given index.

If the caller uses track.play(), index will be undefined, which isn't a number, so that test will fail, and then we'll continue with the else if test. If there's a selected track, we use that (first stopping the current track if it's different).

If there's no selected track, we fall through to the final else clause, which uses the index property of the current object.

Body:
I'm going through this tutorial for a simple playlist with Vue.

I'm confused by the author's play() function, particularly the series of if-else statements. It appears to check whether index is a number, and if it is (and I can't imagine how it wouldn't be), it seems to skip the rest of the code that checks for whether the selected track is the same as the current track, among other things (link to the repo and function in question here):

play (index) {
  let selectedTrackIndex = this.playlist.findIndex(track => track === this.selectedTrack)

  if (typeof index === 'number') {
    index = index

  } else if (this.selectedTrack) {
    if (this.selectedTrack != this.currentTrack) {
      this.stop()
    }
    index = selectedTrackIndex
  } else {
    index = this.index
  }

  let track = this.playlist[index].howl

  if (track.playing()) {
    return
  } else {
    track.play()
  }

  this.selectedTrack = this.playlist[index]
  this.playing = true
  this.index = index
}

The author's summary of the above code:

The method takes an index as the parameter, which specifies the track
  to be played. First, we get the index of the selected track. Then, we
  make some checks to determine the value of the index. If an index is
  provided as an argument and it's a number, then we use it. If a track
  is selected, we use the index of the selected track. If the selected
  track is different from the current one, we use the stop() method to
  stop the current one. Finally, if neither an index argument is passed
  nor a track is selected, we use the value of the index data property.

I checked MDN and a few other sources and didn't see anything special about an if() followed by an else if() in JavaScript. So I figure I have to be missing something here. Why is a validation check on index tied to checking whether the selected track is the same as the current track? The other checks inside the else if() and else blocks seem like stuff you wouldn't want to leave out, and yet his live demo of the app works. I asked the author to elaborate in the comments of the article but the article is almost a year old, so I'm not sure if he'll get back to me. Thanks to everyone in advance.


问:
idea: too many module declarations found
I want to create hello world java 9 application and start it in intellij idea.

Now I have following structure:

content of inner module-info.java:

```<code>module my.module.Second {
    requires my.module.First;
}
</code>```

content of outer module-info.java:

```<code>module my.module.First {
    exports my.pack;
}
</code>```

But idea complains about my project:

```<code>Error:(1, 1) java: too many module declarations found
</code>```

I don't understand why it happens and what really wrong. So

Question:

My question is how to force idea to accept my hello world.

P.S.
From the first glance error looks obvious but I have project which I downloaded from github with the same structure but it works properly and idea doesn't complain about it:

答:
According to Oracle Jar file specification

A modular JAR file is a JAR file that has a module descriptor,
  module-info.class, in the top-level directory (or root) directory.

One Jar could contain only one module.

To fix you problem you have to split your project (create several maven modules)

Body:
I want to create hello world java 9 application and start it in intellij idea.

Now I have following structure:

content of inner module-info.java:

module my.module.Second {
    requires my.module.First;
}

content of outer module-info.java:

module my.module.First {
    exports my.pack;
}

But idea complains about my project:

Error:(1, 1) java: too many module declarations found

I don't understand why it happens and what really wrong. So

Question:

My question is how to force idea to accept my hello world.

P.S.
From the first glance error looks obvious but I have project which I downloaded from github with the same structure but it works properly and idea doesn't complain about it:


问:
How do I extract a list of URLs off a page with selenium?
I am attempting to extract all urls that https://shop.freedommobile.ca/devices has when you click the 'see options' button under each phone and place them into a list of strings.

I am using python with Selenium and wait libraries.
Ive already tried using .text in my parameters. However, I keep running into an error that states:

typeError: 'str' object is not callable
line 17 is the issue.

```<code>from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

class phoneCost:

    driver.get("https://shop.freedommobile.ca/devices")

    # extract the names of the phones
    wait = WebDriverWait(driver, 20) #10 second wait
    XPathLocation = """B//*[@id="skip-navigation"]/div/div/div[1]/div/div[2]/a'"""
    phonePlanLinksRaw = wait.until(EC.presence_of_all_elements_located(By.XPATH(XPathLocation)))
    phonePlanLinks = []

    for element in range(len(phonePlanLinksRaw)):
        link = element
        phonePlanLinks.append(str(link))

    numLink = 1
    for element in range(len(phonePlanLinks)):
        print("phone " + str(numLink) + " : " + phonePlanLinks[element])
        numLink += 1
</code>```

should return a list of urls in string format:

[https://shop.freedommobile.ca/devices/Apple/iPhone_XS_Max?sku=190198786135&planSku=Freedom%20Big%20Gig%2015GB

,

https://shop.freedommobile.ca/devices/Apple/iPhone_XS?sku=190198790569&planSku=Freedom%20Big%20Gig%

,

https://shop.freedommobile.ca/devices/Apple/iPhone_XR?sku=190198776631&planSku=Freedom%20Big%20Gig%2015GB]

Any help is appreciated
Thank you

Body:
I am attempting to extract all urls that https://shop.freedommobile.ca/devices has when you click the 'see options' button under each phone and place them into a list of strings.

I am using python with Selenium and wait libraries.
Ive already tried using .text in my parameters. However, I keep running into an error that states:

typeError: 'str' object is not callable
line 17 is the issue.

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

class phoneCost:

    driver.get("https://shop.freedommobile.ca/devices")

    # extract the names of the phones
    wait = WebDriverWait(driver, 20) #10 second wait
    XPathLocation = """B//*[@id="skip-navigation"]/div/div/div[1]/div/div[2]/a'"""
    phonePlanLinksRaw = wait.until(EC.presence_of_all_elements_located(By.XPATH(XPathLocation)))
    phonePlanLinks = []

    for element in range(len(phonePlanLinksRaw)):
        link = element
        phonePlanLinks.append(str(link))

    numLink = 1
    for element in range(len(phonePlanLinks)):
        print("phone " + str(numLink) + " : " + phonePlanLinks[element])
        numLink += 1

should return a list of urls in string format:

[https://shop.freedommobile.ca/devices/Apple/iPhone_XS_Max?sku=190198786135&planSku=Freedom%20Big%20Gig%2015GB

,

https://shop.freedommobile.ca/devices/Apple/iPhone_XS?sku=190198790569&planSku=Freedom%20Big%20Gig%

,

https://shop.freedommobile.ca/devices/Apple/iPhone_XR?sku=190198776631&planSku=Freedom%20Big%20Gig%2015GB]

Any help is appreciated
Thank you

Body:
Here is the logic that you should use.

WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.XPATH,"//div[starts-with(@class,'deviceListItem')]/a")))
mblOptions = driver.find_elements_by_xpath("//div[starts-with(@class,'deviceListItem')]/a")
mblUrls = []
for mblOption in mblOptions:
    mblUrls.append(mblOption.get_attribute('href'))

print (mblUrls)

output:

['https://shop.freedommobile.ca/devices/Apple/iPhone_XS_Max?sku=190198786135&planSku=Freedom%20Big%20Gig%2015GB', 'https://shop.freedommobile.ca/devices/Apple/iPhone_XS?sku=190198790569&planSku=Freedom%20Big%20Gig%2015GB', 'https://shop.freedommobile.ca/devices/Apple/iPhone_XR?sku=190198776631&planSku=Freedom%20Big%20Gig%2015GB', 'https://shop.freedommobile.ca/devices/Apple/iPhone_8_Plus?sku=190198454249&planSku=Freedom%20Big%20Gig%20%2B%20Talk%205GB', 'https://shop.freedommobile.ca/devices/Apple/iPhone_8?sku=190198450944&planSku=Freedom%20Big%20Gig%20%2B%20Talk%205GB', 'https://shop.freedommobile.ca/devices/Samsung/Galaxy_S10+?sku=887276301570&planSku=Freedom%20Big%20Gig%20%2B%20Talk%205GB', 'https://shop.freedommobile.ca/devices/Samsung/Galaxy_S10?sku=887276312163&planSku=Freedom%20Big%20Gig%20%2B%20Talk%2015GB', 'https://shop.freedommobile.ca/devices/Samsung/Galaxy_S10e?sku=887276313870&planSku=Freedom%20Big%20Gig%2015GB', 'https://shop.freedommobile.ca/devices/Samsung/Galaxy_Tab_A_8_LTE?sku=887276299440&planSku=Promo%20Tablet%2015', 'https://shop.freedommobile.ca/devices/Samsung/Galaxy_Note9?sku=887276279916&planSku=Freedom%20Big%20Gig%2015GB', 'https://shop.freedommobile.ca/devices/Samsung/Galaxy_S9?sku=887276250861&planSku=Freedom%20Big%20Gig%20%2B%20Talk%205GB', 'https://shop.freedommobile.ca/devices/Motorola/G7_Power?sku=723755134249&planSku=Freedom%20Big%20Gig%20%2B%20Talk%205GB', 'https://shop.freedommobile.ca/devices/Motorola/Moto_E5_Play?sku=723755125940&planSku=Freedom%20LTE%2B3G%209.5GB%20Promo', 'https://shop.freedommobile.ca/devices/Google/Pixel_3a?sku=842776111326&planSku=Freedom%20Big%20Gig%20%2B%20Talk%205GB', 'https://shop.freedommobile.ca/devices/Google/Pixel_3?sku=842776109798&planSku=Freedom%20Big%20Gig%20%2B%20Talk%2010GB', 'https://shop.freedommobile.ca/devices/Google/Pixel_3_XL?sku=842776109828&planSku=Freedom%20Big%20Gig%20%2B%20Talk%2010GB', 'https://shop.freedommobile.ca/devices/ZTE/Z557?sku=885913107448&planSku=Freedom%20500MB', 'https://shop.freedommobile.ca/devices/LG/G7_ThinQ?sku=652810830737&planSku=Freedom%20Big%20Gig%20%2B%20Talk%205GB', 'https://shop.freedommobile.ca/devices/Huawei/P30_lite?sku=886598061131&planSku=Freedom%20Big%20Gig%20%2B%20Talk%205GB', 'https://shop.freedommobile.ca/devices/Huawei/Mate_20_Pro?sku=886598058964&planSku=Freedom%20Big%20Gig%20%2B%20Talk%2010GB', 'https://shop.freedommobile.ca/devices/LG/X_Power_3?sku=652810831130&planSku=Freedom%20LTE%2B3G%209.5GB%20Promo', 'https://shop.freedommobile.ca/devices/LG/G8_ThinQ?sku=652810832434&planSku=Freedom%20Big%20Gig%20%2B%20Talk%2010GB', 'https://shop.freedommobile.ca/devices/LG/Q_Stylo_+?sku=652810831222&planSku=Freedom%202GB', 'https://shop.freedommobile.ca/devices/Alcatel/GoFLIP?sku=889063504010&planSku=Freedom%20500MB', 'https://shop.freedommobile.ca/devices/Bring_Your/Own_Device?sku=byod']


问:
In Eclipse, how do I replace a character by a new line?
In Eclipse 3.3.2, I would like to replace a character (say ',') by a new line in a file.
What should I write in the "Replace with" box in order to do so ?

EDIT : Many answers seems to be for Eclipse 3.4. Is there a solution for Eclipse 3.3.X ?

答: I'm using Helios and it works, however I had some issues with replacement... I wanted to place a line break between any of these brackets "><" (to make each new XML tag go to a new line)... first I had to place a chacter between the 2 brackets, for instance /r, after this i checked the "regular expressions" box and replaced the /r with \R, which resulted in the correct linebreak. otherwise, the replace seemed to be greyed out.</p>

OwnerDisplayName: paulgreg

ContentLicense: CC BY-SA 2.5

LastEditorDisplayName: Craig Angus

ContentLicense: CC BY-SA 3.0


问:
sabre: looping through TEL-property doesn´t provide what expected
A probably simple question - but I´m blockheaded:

Following sabre/vobject usage instruction I will loop the TEL-property to get numbers and their types.

```<code>BEGIN:VCARD
TEL;TYPE=HOME,PREF:+15551234560
TEL;TYPE=HOME,FAX:+15551234569
TEL;TYPE=WORK:+155523456789
END:VCARD
</code>```

```<code>foreach ($vCard->TEL as $number) {
    echo (string)$number . ': ' . $vCard->TEL['TYPE'] . PHP_EOL;
}
</code>```

Instead of

```<code>+15551234560: HOME,PREF
+15551234569: HOME,FAX
+155523456789: WORK
</code>```

I receive:

```<code>+15551234560: HOME,PREF
+15551234569: HOME,PREF
+155523456789: HOME,PREF
</code>```

答:
```<code>foreach ($vCard->TEL as $number) {
    echo (string)$number . ': ' . $number['TYPE'] . PHP_EOL;
}
</code>```

Body:
A probably simple question - but I´m blockheaded:

Following sabre/vobject usage instruction I will loop the TEL-property to get numbers and their types.

BEGIN:VCARD
TEL;TYPE=HOME,PREF:+15551234560
TEL;TYPE=HOME,FAX:+15551234569
TEL;TYPE=WORK:+155523456789
END:VCARD

foreach ($vCard->TEL as $number) {
    echo (string)$number . ': ' . $vCard->TEL['TYPE'] . PHP_EOL;
}

Instead of

+15551234560: HOME,PREF
+15551234569: HOME,FAX
+155523456789: WORK

I receive:

+15551234560: HOME,PREF
+15551234569: HOME,PREF
+155523456789: HOME,PREF


问:
bash looping through file to find beginning of string
I have a large textfile with ~ 10,000 lines of data, whereby each line may have a different number of columns. For example:

```<code>789 KKPP 2018 08 09 10 20 30 AUTO A2987 10SM 5-MIN 22/13
790 KGOX 2018 08 09 10 20 35 AUTO P0002 21/19
...
798 KLXZ 2018 08 09 10 20 40 AUTO 18013GT 7SM 21/16 RMK A02 T02060156
799 KMNO 2018 08 09 10 20 45 AUTO 10SM P0001
...
...
</code>```

I want to loop through every line and extract the 2nd column in which the prefix "P00*" appears. For example, in the above snippet of the file, I would want:

```<code>KGOX P0002
KMNO P0001
</code>```

Which correspond to the lines 790 and 799. The number of columns are completely random, and can change from one row to the next. The most important thing is that somewhere in the row, some column of text starts with "P00".

I have a simple while read loop:

```<code> while IFS='' read -r line || [[ -n "${line}" ]];
 do
 temp=$(echo ${line} | awk '{print $7}')
 if [[ ${temp:0:3} == "P00" ]];
 then
 data=${temp}
 fi
 done
</code>```

But this gets messy quickly, as the column numbers can exceed 30. Is there a simpler way to get this information and, perhaps, write to a text file? I know awk can do something that might work but can't get anything to work properly.

答:
Getting the 2nd column is the tricky part, since it's not always in the same place. There are some better answers with regexes (the match function is very handy), but a brute force approach is to print field two followed by every other field on the current line, then find the ones that match P00.</p>

```<code>awk '{fld2=$2 ; split($0, a) ; for (f in a) { print fld2 " " a[f] } }' t | grep 'P00*'
KGOX P0002
KMNO P0001
</code>```

Body:
I have a large textfile with ~ 10,000 lines of data, whereby each line may have a different number of columns. For example:

789 KKPP 2018 08 09 10 20 30 AUTO A2987 10SM 5-MIN 22/13
790 KGOX 2018 08 09 10 20 35 AUTO P0002 21/19
...
798 KLXZ 2018 08 09 10 20 40 AUTO 18013GT 7SM 21/16 RMK A02 T02060156
799 KMNO 2018 08 09 10 20 45 AUTO 10SM P0001
...
...

I want to loop through every line and extract the 2nd column in which the prefix "P00*" appears. For example, in the above snippet of the file, I would want:

KGOX P0002
KMNO P0001

Which correspond to the lines 790 and 799. The number of columns are completely random, and can change from one row to the next. The most important thing is that somewhere in the row, some column of text starts with "P00".

I have a simple while read loop:

 while IFS='' read -r line || [[ -n "${line}" ]];
 do
 temp=$(echo ${line} | awk '{print $7}')
 if [[ ${temp:0:3} == "P00" ]];
 then
 data=${temp}
 fi
 done

But this gets messy quickly, as the column numbers can exceed 30. Is there a simpler way to get this information and, perhaps, write to a text file? I know awk can do something that might work but can't get anything to work properly.

Body:
Getting the 2nd column is the tricky part, since it's not always in the same place. There are some better answers with regexes (the match function is very handy), but a brute force approach is to print field two followed by every other field on the current line, then find the ones that match P00.

awk '{fld2=$2 ; split($0, a) ; for (f in a) { print fld2 " " a[f] } }' t | grep 'P00*'
KGOX P0002
KMNO P0001


问:
How do I extract data from the 3rd column of multiple large text files based on first two matching columns?
I have 3 large text files (>16 M lines each) in the format below.

Contents of file 1:

```<code>22_0F3, 33_0F4, 0.87
28_0F3, 37_0F4, 0.79
21_0F5, 39_2F1, 0.86
</code>```

Contents of file 2:

```<code>22_0F3, 33_0F4, 1000
28_0F3, 37_0F4, 1500
21_0F2, 52_2F8, 3600
</code>```

Contents of file 3:

```<code>22_0F3, 33_0F4, 0.75
28_0F3, 37_0F4, 0.91
81_0F2, 32_2F1, 0.84
</code>```

I'm trying to extract the common lines based on 1st two fields from these 3 files.

Then I have to find the square root of the squares of each corresponding value from the 3rd column in each line (explained below).

The difficulty is that since these text files are really huge with more than 16 million lines, it is taking more time to load and extract common lines.

The common lines would be around 15M based on the data I have.

Intermediate output is something like this:

```<code>22_0F3, 33_0F4, 0.87, 1000, 0.75
28_0F3, 37_0F4, 0.79, 1500, 0.91
</code>```

The desired output is:

```<code>22_0F3, 33_0F4, 1000.7575
28_0F3, 37_0F4, 1500.6245
</code>```

where 1000.7575 is the square root of sum of squares of 0.87, 1000, and 0.75.

How can I get the desired output from these huge files without much delay?

答:
You could scan the 3 files and build a dictionary in memory with the code pair as key and the list of numbers as value.  A dictionary with 16 million small items should be no problem for most modern PCs.  Then go through the dictionary, make your calculation on items that have 3 values in the list and write them to the output file.

```<code># Aggregation (build dictionary of lists) ...

from collections import defaultdict
data = defaultdict(list)
for fileName in ["file1.txt","file2.txt","file3.txt"]:
    with open(fileName,'r') as lines:
        for line in lines:
            col1,col2,value = line.split(",")
            if col1>col2 : col1,col2 = col2,col1 # match codes in any order
            data[(col1,col2)].append(float(value))

# Calculation and output...

from math import sqrt
with open("output.txt","w") as output:
    for (col1,col2),values in data.items():
        if len(values) < 3: continue             # must have the 3 matches
        result = sqrt(sum( x*x for x in values)) # use your formula here
        output.write(f"{col1},{col2}, {result}\n")
</code>```

This takes 68 seconds for 15,000,000 matching lines on my laptop.  (but I have an SSD, a hard disk drive may take much longer)

Note that I used the square root of the sum of squares in my calculation.  Based on your example, that's obviously not the right formula because
√(0.87^2 + 1000^2 + 0.75^2) is 1000.0006597 not 1000.7575.  I assume you will replace my √∑n^2 formula with your own calculation for the result.

Body:
I have 3 large text files (>16 M lines each) in the format below.

Contents of file 1:

22_0F3, 33_0F4, 0.87
28_0F3, 37_0F4, 0.79
21_0F5, 39_2F1, 0.86

Contents of file 2:

22_0F3, 33_0F4, 1000
28_0F3, 37_0F4, 1500
21_0F2, 52_2F8, 3600

Contents of file 3:

22_0F3, 33_0F4, 0.75
28_0F3, 37_0F4, 0.91
81_0F2, 32_2F1, 0.84

I'm trying to extract the common lines based on 1st two fields from these 3 files.

Then I have to find the square root of the squares of each corresponding value from the 3rd column in each line (explained below).

The difficulty is that since these text files are really huge with more than 16 million lines, it is taking more time to load and extract common lines.

The common lines would be around 15M based on the data I have.

Intermediate output is something like this:

22_0F3, 33_0F4, 0.87, 1000, 0.75
28_0F3, 37_0F4, 0.79, 1500, 0.91

The desired output is:

22_0F3, 33_0F4, 1000.7575
28_0F3, 37_0F4, 1500.6245

where 1000.7575 is the square root of sum of squares of 0.87, 1000, and 0.75.

How can I get the desired output from these huge files without much delay?

Body:
You could scan the 3 files and build a dictionary in memory with the code pair as key and the list of numbers as value.  A dictionary with 16 million small items should be no problem for most modern PCs.  Then go through the dictionary, make your calculation on items that have 3 values in the list and write them to the output file.

# Aggregation (build dictionary of lists) ...

from collections import defaultdict
data = defaultdict(list)
for fileName in ["file1.txt","file2.txt","file3.txt"]:
    with open(fileName,'r') as lines:
        for line in lines:
            col1,col2,value = line.split(",")
            if col1>col2 : col1,col2 = col2,col1 # match codes in any order
            data[(col1,col2)].append(float(value))

# Calculation and output...

from math import sqrt
with open("output.txt","w") as output:
    for (col1,col2),values in data.items():
        if len(values) < 3: continue             # must have the 3 matches
        result = sqrt(sum( x*x for x in values)) # use your formula here
        output.write(f"{col1},{col2}, {result}\n")

This takes 68 seconds for 15,000,000 matching lines on my laptop.  (but I have an SSD, a hard disk drive may take much longer)

Note that I used the square root of the sum of squares in my calculation.  Based on your example, that's obviously not the right formula because
√(0.87^2 + 1000^2 + 0.75^2) is 1000.0006597 not 1000.7575.  I assume you will replace my √∑n^2 formula with your own calculation for the result.


问:
How to write stored procedure in DB2
Please Help me in to write the stored procedure in Db2.

```<code>CREATE PROCEDURE assedt
BEGIN

 SELECT ASSETNUM FROM ASSET
END
</code>```

I tried the above code it is throwing an error like below:

Error report -
  DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=SELECT ASSETNUM;ROCEDURE p1
  BEGIN

;, DRIVER=4.12.55

答:
Example:

```<code>create table test_table (numcol integer);

insert into test_table values (1);

CREATE OR REPLACE procedure assedt (out out_var integer)
language sql
p1: begin
declare l_var integer;
   select max(numcol) into l_var from test_table;
   set out_var = l_var + 1;
end p1;

begin
declare g_var integer;
call assedt( g_var );
insert into test_table values (g_var);
end;

select * from test_table;
</code>```

Explanation, per G_V's suggestion: this procedure, somewhat styled as your original, takes a max value from test_table, increments it, and returns it in the out parameter (a-la Oracle's nextval()). The anonymous block after the procedure, executes the proc, grabs the new maximum and then inserts it back into the test_table outside the proc. This gives you the perspective of interaction between stored code and anonymous code, and how you can pass values and parameters. Hope this helps.

Title: How to write stored procedure in DB2

Body:
Please Help me in to write the stored procedure in Db2.

CREATE PROCEDURE assedt
BEGIN

 SELECT ASSETNUM FROM ASSET
END

I tried the above code it is throwing an error like below:

Error report -
  DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=SELECT ASSETNUM;ROCEDURE p1
  BEGIN

;, DRIVER=4.12.55

Body:
Example:

create table test_table (numcol integer);

insert into test_table values (1);

CREATE OR REPLACE procedure assedt (out out_var integer)
language sql
p1: begin
declare l_var integer;
   select max(numcol) into l_var from test_table;
   set out_var = l_var + 1;
end p1;

begin
declare g_var integer;
call assedt( g_var );
insert into test_table values (g_var);
end;

select * from test_table;

Explanation, per G_V's suggestion: this procedure, somewhat styled as your original, takes a max value from test_table, increments it, and returns it in the out parameter (a-la Oracle's nextval()). The anonymous block after the procedure, executes the proc, grabs the new maximum and then inserts it back into the test_table outside the proc. This gives you the perspective of interaction between stored code and anonymous code, and how you can pass values and parameters. Hope this helps.


问:
Best Way to externalize system properties on a multi-environment application
We are working with a Spring 3 application that runs on several environments (test, UAT and Production) these environments are managed by a third party company so we have almost no access to the servers.

We have tried with Jboss System Properties and Maven2 Profiles. Both solutions worked fine, however we don't want to tie the application to one specific Server (Jboss in this case) and we don't want to do environment specific builds (required for Maven2 profiles).

Is there a good way we could have environment specific properties for the app that do not require different builds for each environment and require no modifications on the server side and that could also run on different servers? (some sort of PropertyPlaceHolderConfigurer that could read property files outside the app context should do the trick)

答:
Environment-specific builds are not a bad option.

But spring 3.1 is providing what you are looking for - environment specific configuration. See this and this


问:
Conditional aggregation in SQL Server based on a column value
My data is something like:

```
IdType     Date        ActualEst      Value     PriceType
  1        01-06         A            1          Settle
  1        02-06         A            2          Settle
  1        02-06         F            3          Settle
  1        03-06         A            4          Settle
  2        01-06         A            5          Settle
  2        02-06         A            6          Settle
  2        03-06         F            7          Settle
```

I want to do a average on "Value" column, grouping on "IdType" and "PriceType" columns such that if for a particular Date (column), ActualEst has records for both 'A' and 'F', I choose 'A' over 'F', otherwise any of them if only one of them exists for a Date.

So, for above data I should be picking these records for averaging Value:

```
IdType      Date           ActualEst       Value     PriceType
  1          01-06           A              1          Settle
  1          02-06           A              2          Settle
  1          03-06           A              4          Settle
```

as for date of 02-06 both 'A' and 'F' records exist and I give priority to 'A' if both types of records exist for a date.

second group..

```
IdType      Date           ActualEst       Value     PriceType
  2          01-06           A              5          Settle
  2          02-06           A              6          Settle
  2          03-06           F              7          Settle
```

and so on...

答:
Row_number() the rows according to the priority needed and select only top priority rows:</p>

```<code>with tbl as (
    -- source data
    select * from
    (values
         (1 ,'01-06','A',1,'Settle')
        ,(1 ,'02-06','A',2,'Settle')
        ,(1 ,'02-06','F',3,'Settle')
        ,(1 ,'03-06','A',4,'Settle')
        ,(2 ,'01-06','A',5,'Settle')
        ,(2 ,'02-06','A',6,'Settle')
        ,(2 ,'03-06','F',7,'Settle')
    ) t (IdType, [Date],ActualEst,Value,PriceType)
),
-- the query
prioritized as(
    select IdType, [Date],ActualEst,Value,PriceType,
      rn = row_number() over(partition by IdType, [Date] order by ActualEst)
    from tbl
)
select IdType, [Date], avg(value) v
from prioritized
where rn=1
group by IdType, [Date];
</code>```

Body:
My data is something like:

IdType     Date        ActualEst      Value     PriceType
  1        01-06         A            1          Settle
  1        02-06         A            2          Settle
  1        02-06         F            3          Settle
  1        03-06         A            4          Settle
  2        01-06         A            5          Settle
  2        02-06         A            6          Settle
  2        03-06         F            7          Settle

I want to do a average on "Value" column, grouping on "IdType" and "PriceType" columns such that if for a particular Date (column), ActualEst has records for both 'A' and 'F', I choose 'A' over 'F', otherwise any of them if only one of them exists for a Date.

So, for above data I should be picking these records for averaging Value:

IdType      Date           ActualEst       Value     PriceType
  1          01-06           A              1          Settle
  1          02-06           A              2          Settle
  1          03-06           A              4          Settle

as for date of 02-06 both 'A' and 'F' records exist and I give priority to 'A' if both types of records exist for a date.

second group..

IdType      Date           ActualEst       Value     PriceType
  2          01-06           A              5          Settle
  2          02-06           A              6          Settle
  2          03-06           F              7          Settle

and so on...

Body:
Row_number() the rows according to the priority needed and select only top priority rows:

with tbl as (
    -- source data
    select * from
    (values
         (1 ,'01-06','A',1,'Settle')
        ,(1 ,'02-06','A',2,'Settle')
        ,(1 ,'02-06','F',3,'Settle')
        ,(1 ,'03-06','A',4,'Settle')
        ,(2 ,'01-06','A',5,'Settle')
        ,(2 ,'02-06','A',6,'Settle')
        ,(2 ,'03-06','F',7,'Settle')
    ) t (IdType, [Date],ActualEst,Value,PriceType)
),
-- the query
prioritized as(
    select IdType, [Date],ActualEst,Value,PriceType,
      rn = row_number() over(partition by IdType, [Date] order by ActualEst)
    from tbl
)
select IdType, [Date], avg(value) v
from prioritized
where rn=1
group by IdType, [Date];


问:
RegEx for matching an alphanumeric pattern with quantifier
I am trying to limit the digits between 4 and 6 in my regex but it is not working

Minimum range works but the max range does not work:

Some Text-1  = validates

Some Text-201901 = validates

Some Text-20190101 = passes the validation where it should fail

Now if I add $ at the end then none of the above work.

Code:

```<code>^[A-Z ]{3,}-\d{4,6}
</code>```

答:
You want to use

```<code>^[A-Z ]{3,}-[0-9]{3,6}(?!\d)
</code>```

Details

^ - start of a string

[A-Z ]{3,} - three or more uppercase letters or spaces

- - a hyphen

[0-9]{3,6} - three to six digits

(?!\d) - a negative lookahead that fails the match if, immediately to the right of the current location, there is a digit.

Body:
I am trying to limit the digits between 4 and 6 in my regex but it is not working

Minimum range works but the max range does not work:

Some Text-1  = validates

Some Text-201901 = validates

Some Text-20190101 = passes the validation where it should fail

Now if I add $ at the end then none of the above work.

Code:

^[A-Z ]{3,}-\d{4,6}

Body:
You want to use

^[A-Z ]{3,}-[0-9]{3,6}(?!\d)

Details

^ - start of a string

[A-Z ]{3,} - three or more uppercase letters or spaces

- - a hyphen

[0-9]{3,6} - three to six digits

(?!\d) - a negative lookahead that fails the match if, immediately to the right of the current location, there is a digit.


问:
If statement not working when used inside an action listener
I'm pretty new to java and have been working on learning how GUI's work. Through some tutorials, I managed to piece together a program to use a text box with the hope to incorporate a calculator I made as my first project. The area I'm focusing on is the button and action listener, where I'm trying to get an extra response when typing in "calc".

I've tried initializing the extra response outside of the program, but because of the string being called inside, I can't get it to work. I also tried calling the string outside but that still didn't work. I have an idea doing anything past this will require separately called functions, but I was hoping to start by figuring out this smaller part first.

```<code>    static JTextField tf;
    static JFrame frame;
    static JPanel panel;
    static JTextArea ta;
    int count;
    int num1;
    int num2;
    int exp;
    char operator;
    double answer;

    static void GUI() {
        frame = new JFrame("Thank you for reading this");
        panel = new JPanel();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,400);
        JButton button = new JButton("Test");
        tf = new JTextField(15);
        panel.add(tf);
        panel.add(button);

        JTextArea ta = new JTextArea();
        ta.setEditable(false);

        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                String text = tf.getText();
                ta.append(text+"\n");
                if(text == "q") {
                    ta.append("something random\n");
                }
            }
        });

        frame.getContentPane().add(BorderLayout.CENTER, ta);
        frame.getContentPane().add(BorderLayout.SOUTH, panel);
        frame.setVisible(true);
    }

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

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub

    }

}
</code>```

I'm expecting to see "something random" appear below "calc" when it is typed into the text field. So far I receive nothing with the if statement

答:
Firstly, == Operator matches the reference of Strings or Objects not the actual value. String is not a primitive data type so that you can compare its value by using ==. You need to call equals() method for this:

```<code>if(text.equals("q")) {
      ta.append("something random\n");
}
</code>```

Body:
I'm pretty new to java and have been working on learning how GUI's work. Through some tutorials, I managed to piece together a program to use a text box with the hope to incorporate a calculator I made as my first project. The area I'm focusing on is the button and action listener, where I'm trying to get an extra response when typing in "calc".

I've tried initializing the extra response outside of the program, but because of the string being called inside, I can't get it to work. I also tried calling the string outside but that still didn't work. I have an idea doing anything past this will require separately called functions, but I was hoping to start by figuring out this smaller part first.

    static JTextField tf;
    static JFrame frame;
    static JPanel panel;
    static JTextArea ta;
    int count;
    int num1;
    int num2;
    int exp;
    char operator;
    double answer;

    static void GUI() {
        frame = new JFrame("Thank you for reading this");
        panel = new JPanel();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,400);
        JButton button = new JButton("Test");
        tf = new JTextField(15);
        panel.add(tf);
        panel.add(button);

        JTextArea ta = new JTextArea();
        ta.setEditable(false);

        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                String text = tf.getText();
                ta.append(text+"\n");
                if(text == "q") {
                    ta.append("something random\n");
                }
            }
        });

        frame.getContentPane().add(BorderLayout.CENTER, ta);
        frame.getContentPane().add(BorderLayout.SOUTH, panel);
        frame.setVisible(true);
    }

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

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub

    }

}

I'm expecting to see "something random" appear below "calc" when it is typed into the text field. So far I receive nothing with the if statement

Body:
Firstly, == Operator matches the reference of Strings or Objects not the actual value. String is not a primitive data type so that you can compare its value by using ==. You need to call equals() method for this:

if(text.equals("q")) {
      ta.append("something random\n");
}


问:
Custom data provider?
I have a database which does not provide (yet) c# client library, only a binary tcp or http rest protocol.

I have to write an application that can perform various operations on the DB : CRUD, management, etc.

These operation are expressed in a sql query, with select/insert/update/delete and custom keywords for DB-specific operations.

I'm wondering what is the path to this result. I can ask the question in two point of views : in an ideal world, and in a practical world.

I'd appreciate any feedback !What is the recommended approach, problems encountered, etc.

PS: I'm thinking over these approaches :

writing a custom ADO.Net provider (IDbCommand, IDbConnection, etc.)

writing a custom linq provider (which relies on the former)

maybe writing a EF provider

答: Linq is just language integrated query. It is syntax to express query but in case of database querying it just creates expression tree which must be translated to SQL and executed somehow. For this execution ADO.NET provider is used. The same states for Entity framework which rely on ADO.NET provider to access the database. So  if you want to create some implementation you should start with ADO.NET provider anyway.</p>

Title: Custom data provider?


问:
What happens to old activity after starting a new intent?
what happens to the rest of the code of older activity after starting a new activity? here 'doSomeWork()' is called or not? does startActivity() work as a return statement?</p>

```<code>public void method(){
    Intent intent = new Intent(this, newactivity.class);
    startActivity(intent);
    doSomeWork();
}
</code>```

答:
here 'doSomeWork()' is called or not?

It will be called immediately. startActivity() is not a blocking call. newactivity will not be started by the time startActivity() returns.

does startActivity() work as a return statement?

No.

Body:
what happens to the rest of the code of older activity after starting a new activity? here 'doSomeWork()' is called or not? does startActivity() work as a return statement?

public void method(){
    Intent intent = new Intent(this, newactivity.class);
    startActivity(intent);
    doSomeWork();
}


问:
Why is Vue v-bind:class not updating?
Updating data property does not update dynamic class.

Have tried setting data property through computed value.

```<code><div class="customize-box" v-on:click="select" v-bind:class="{active: customizeBoxVisible}"></div>
<script>
    export default {
        data() {
            return {
                isSelected: false
            }
        },
        computed: {
            customizeBoxVisible: {
                get() {
                    return this.isSelected;
                },
                set(value) {
                    this.isSelected = value;
                }
            }
       },
       methods: {
            select() {
                this.isSelected = true;
            }
        }
   }
</script>
</code>```

Inspecting component data in chrome dev tools shows that customizeBoxVisible is set to true. After toggling isSelected in dev tools, class gets applied.

答: Turns out I was migrating from a jQuery to a Vue.js application and forgot to remove a click handler which removed the active class from my element. Everything works as expected.</p>

Title: Why is Vue v-bind:class not updating?

Body:
Updating data property does not update dynamic class.

Have tried setting data property through computed value.

Inspecting component data in chrome dev tools shows that customizeBoxVisible is set to true. After toggling isSelected in dev tools, class gets applied.


答:
When comparing objects for value equality use equals instead of ==, because == is checking reference equality.

So instead of text == "q" write text.equals("q");

Title: If statement not working when used inside an action listener


问:
How to represent complex POST data in python for requests
I'm trying to automate a web form.  The payload when I actually run the query in Chrome looks like this on the inspect window...

```<code>    data: [{"property":"TimeQuick","value":"Active"},{"property":"TimeQuickDurationOptions","value":3},{"property":"TimeQuickStartDate","value":"05/15/2019 00:00:00"},{"property":"TimeQuickEndDate","value":"05/15/2019 23:59:59"},{"property":"ProviderCode","value":["FPL"]},{"property":"SellerCode","value":[""]},{"property":"Ref","value":""},{"property":"POR","value":["SOCO"]},{"property":"POD","value":["FPC"]},{"property":"Path","value":""},{"property":"ServiceIncrement","value":["DAILY"]},{"property":"TSClass","value":[""]},{"property":"TSType","value":[""]},{"property":"TSWindow","value":""},{"property":"TSPeriod","value":""},{"property":"TSSubClass","value":""},{"property":"Time","value":"Active"},{"property":"TimeDurationOptions","value":3},{"property":"TimeStartDate","value":"05/15/2019 00:00:00"},{"property":"TimeEndDate","value":"05/15/2019 23:59:59"},{"property":"ShowActiveData","value":true},{"property":"DaylightSavings","value":false}]
    sort: [{"property":"TOL","direction":"DESC","root":"data"}]
    pagingEnabled: 1
    page: 1
    limit: 50
</code>```

I tried to represent that as a python variable like this

```<code>    datareq = [
             ('data',
              {'property':'TimeQuick', 'value':'Active'},
              {"property":"TimeQuickDurationOptions","value":'3'},
              {"property":"TimeQuickStartDate","value":"05/15/2019 00:00:00"},
              {"property":"TimeQuickEndDate","value":"05/15/2019 23:59:59"},
              {"property":"ProviderCode","value":["FPL"]},
              {"property":"SellerCode","value":[""]},
              {"property":"Ref","value":""},
              {"property":"POR","value":["SOCO"]},
              {"property":"POD","value":["FPC"]},
              {"property":"Path","value":""},
              {"property":"ServiceIncrement","value":["DAILY"]},
              {"property":"TSClass","value":[""]},
              {"property":"TSType","value":[""]},
              {"property":"TSWindow","value":""},
              {"property":"TSPeriod","value":""},
              {"property":"TSSubClass","value":""},
              {"property":"Time","value":"Active"},
              {"property":"TimeDurationOptions","value":3},
              {"property":"TimeStartDate","value":"05/15/2019 00:00:00"},
              {"property":"TimeEndDate","value":"05/15/2019 23:59:59"},
              {"property":"ShowActiveData","value":'true'},
              {"property":"DaylightSavings","value":'false'}
              ),
             ('sort',
              {"property":"TOL","direction":"DESC","root":"data"}
              ),
             ('pagingEnabled', 1),
             ('limit', 50)

             ]
</code>```

When I ran s.post(myurl, data=datareq, cert=mycerts) I got the following error:

```<code>    Traceback (most recent call last):

      File "<ipython-input-78-37ee269ebbce>", line 1, in <module>
        logblah=s.post(myurl, data= datareq, cert=mycerts)

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\sessions.py", line 555, in post
        return self.request('POST', url, data=data, json=json, **kwargs)

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\sessions.py", line 494, in request
        prep = self.prepare_request(req)

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\sessions.py", line 437, in prepare_request
        hooks=merge_hooks(request.hooks, self.hooks),

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\models.py", line 308, in prepare
        self.prepare_body(data, files, json)

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\models.py", line 499, in prepare_body
        body = self._encode_params(data)

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\models.py", line 97, in _encode_params
        for k, vs in to_key_val_list(data):

    ValueError: too many values to unpack (expected 2)
</code>```

I'm assuming the problem is in the way I've structured my datareq variable.  What would be the proper way to make that POST?

Edit/Update:
I've tried each of Alex and Ivan's suggestions but neither work.  They each give me a cryptic message from the server that success=false.  If I try them with json=datareq instead of data=datareq then I get a response from the server with 0 results even though it should have many so it seems like that is getting closer but still not all the way.

答:
Is the server expecting the POST body to be of type application/json or application/x-www-form-urlencoded? If it's json, then use the syntax request.post(url, json=payload_dict, ....) (note the json kwarg instead of data). If you use data then it assumes content type application/x-www-form-urlencoded, and json assume json. If it is indeed expecting json, which would make sense because the data is nested a few levels deep, then I'll expand upon @Işık Kaplan's answer:

```<code># the dict as posted by @Işık Kaplan
payload = {
    "data": [
        {"property": "TimeQuick", "value": "Active"},
        {"property": "TimeQuickDurationOptions", "value": 3},
        {"property": "TimeQuickStartDate", "value": "05/15/2019 00:00:00"},
        {"property": "TimeQuickEndDate", "value": "05/15/2019 23:59:59"},
        {"property": "ProviderCode", "value": ["FPL"]},
        {"property": "SellerCode", "value": [""]},
        {"property": "Ref", "value": ""},
        {"property": "POR", "value": ["SOCO"]},
        {"property": "POD", "value": ["FPC"]},
        {"property": "Path", "value": ""},
        {"property": "ServiceIncrement", "value": ["DAILY"]},
        {"property": "TSClass", "value": [""]},
        {"property": "TSType", "value": [""]},
        {"property": "TSWindow", "value": ""},
        {"property": "TSPeriod", "value": ""},
        {"property": "TSSubClass", "value": ""},
        {"property": "Time", "value": "Active"},
        {"property": "TimeDurationOptions", "value": 3},
        {"property": "TimeStartDate", "value": "05/15/2019 00:00:00"},
        {"property": "TimeEndDate", "value": "05/15/2019 23:59:59"},
        {"property": "ShowActiveData", "value": True},
        {"property": "DaylightSavings", "value": False}],
    "sort": [
        {"property": "TOL", "direction": "DESC", "root": "data"}
    ],
    "pagingEnabled": 1,
    "page": 1,
    "limit": 50,
}

# assuming you have variables named `s`, `myurl`, and `mycerts`
# note `json=payload`, not `data=payload`
s.post(myurl, json=payload, cert=mycerts)
</code>```

Body:
I'm trying to automate a web form.  The payload when I actually run the query in Chrome looks like this on the inspect window...

    data: [{"property":"TimeQuick","value":"Active"},{"property":"TimeQuickDurationOptions","value":3},{"property":"TimeQuickStartDate","value":"05/15/2019 00:00:00"},{"property":"TimeQuickEndDate","value":"05/15/2019 23:59:59"},{"property":"ProviderCode","value":["FPL"]},{"property":"SellerCode","value":[""]},{"property":"Ref","value":""},{"property":"POR","value":["SOCO"]},{"property":"POD","value":["FPC"]},{"property":"Path","value":""},{"property":"ServiceIncrement","value":["DAILY"]},{"property":"TSClass","value":[""]},{"property":"TSType","value":[""]},{"property":"TSWindow","value":""},{"property":"TSPeriod","value":""},{"property":"TSSubClass","value":""},{"property":"Time","value":"Active"},{"property":"TimeDurationOptions","value":3},{"property":"TimeStartDate","value":"05/15/2019 00:00:00"},{"property":"TimeEndDate","value":"05/15/2019 23:59:59"},{"property":"ShowActiveData","value":true},{"property":"DaylightSavings","value":false}]
    sort: [{"property":"TOL","direction":"DESC","root":"data"}]
    pagingEnabled: 1
    page: 1
    limit: 50

I tried to represent that as a python variable like this

    datareq = [
             ('data',
              {'property':'TimeQuick', 'value':'Active'},
              {"property":"TimeQuickDurationOptions","value":'3'},
              {"property":"TimeQuickStartDate","value":"05/15/2019 00:00:00"},
              {"property":"TimeQuickEndDate","value":"05/15/2019 23:59:59"},
              {"property":"ProviderCode","value":["FPL"]},
              {"property":"SellerCode","value":[""]},
              {"property":"Ref","value":""},
              {"property":"POR","value":["SOCO"]},
              {"property":"POD","value":["FPC"]},
              {"property":"Path","value":""},
              {"property":"ServiceIncrement","value":["DAILY"]},
              {"property":"TSClass","value":[""]},
              {"property":"TSType","value":[""]},
              {"property":"TSWindow","value":""},
              {"property":"TSPeriod","value":""},
              {"property":"TSSubClass","value":""},
              {"property":"Time","value":"Active"},
              {"property":"TimeDurationOptions","value":3},
              {"property":"TimeStartDate","value":"05/15/2019 00:00:00"},
              {"property":"TimeEndDate","value":"05/15/2019 23:59:59"},
              {"property":"ShowActiveData","value":'true'},
              {"property":"DaylightSavings","value":'false'}
              ),
             ('sort',
              {"property":"TOL","direction":"DESC","root":"data"}
              ),
             ('pagingEnabled', 1),
             ('limit', 50)

             ]

When I ran s.post(myurl, data=datareq, cert=mycerts) I got the following error:

    Traceback (most recent call last):

      File "<ipython-input-78-37ee269ebbce>", line 1, in <module>
        logblah=s.post(myurl, data= datareq, cert=mycerts)

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\sessions.py", line 555, in post
        return self.request('POST', url, data=data, json=json, **kwargs)

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\sessions.py", line 494, in request
        prep = self.prepare_request(req)

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\sessions.py", line 437, in prepare_request
        hooks=merge_hooks(request.hooks, self.hooks),

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\models.py", line 308, in prepare
        self.prepare_body(data, files, json)

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\models.py", line 499, in prepare_body
        body = self._encode_params(data)

      File "C:\Users\me\AppData\Local\Continuum\anaconda3\Lib\python\requests\models.py", line 97, in _encode_params
        for k, vs in to_key_val_list(data):

    ValueError: too many values to unpack (expected 2)

I'm assuming the problem is in the way I've structured my datareq variable.  What would be the proper way to make that POST?

Edit/Update:
I've tried each of Alex and Ivan's suggestions but neither work.  They each give me a cryptic message from the server that success=false.  If I try them with json=datareq instead of data=datareq then I get a response from the server with 0 results even though it should have many so it seems like that is getting closer but still not all the way.

Body:
Is the server expecting the POST body to be of type application/json or application/x-www-form-urlencoded? If it's json, then use the syntax request.post(url, json=payload_dict, ....) (note the json kwarg instead of data). If you use data then it assumes content type application/x-www-form-urlencoded, and json assume json. If it is indeed expecting json, which would make sense because the data is nested a few levels deep, then I'll expand upon @Işık Kaplan's answer:

# the dict as posted by @Işık Kaplan
payload = {
    "data": [
        {"property": "TimeQuick", "value": "Active"},
        {"property": "TimeQuickDurationOptions", "value": 3},
        {"property": "TimeQuickStartDate", "value": "05/15/2019 00:00:00"},
        {"property": "TimeQuickEndDate", "value": "05/15/2019 23:59:59"},
        {"property": "ProviderCode", "value": ["FPL"]},
        {"property": "SellerCode", "value": [""]},
        {"property": "Ref", "value": ""},
        {"property": "POR", "value": ["SOCO"]},
        {"property": "POD", "value": ["FPC"]},
        {"property": "Path", "value": ""},
        {"property": "ServiceIncrement", "value": ["DAILY"]},
        {"property": "TSClass", "value": [""]},
        {"property": "TSType", "value": [""]},
        {"property": "TSWindow", "value": ""},
        {"property": "TSPeriod", "value": ""},
        {"property": "TSSubClass", "value": ""},
        {"property": "Time", "value": "Active"},
        {"property": "TimeDurationOptions", "value": 3},
        {"property": "TimeStartDate", "value": "05/15/2019 00:00:00"},
        {"property": "TimeEndDate", "value": "05/15/2019 23:59:59"},
        {"property": "ShowActiveData", "value": True},
        {"property": "DaylightSavings", "value": False}],
    "sort": [
        {"property": "TOL", "direction": "DESC", "root": "data"}
    ],
    "pagingEnabled": 1,
    "page": 1,
    "limit": 50,
}

# assuming you have variables named `s`, `myurl`, and `mycerts`
# note `json=payload`, not `data=payload`
s.post(myurl, json=payload, cert=mycerts)


问:
Couldn't open Windows GDI printer driver
I have virtual printer installed which prints through redirected port and sends document to real printer via gsview\gsprint.exe. It works normally when I use gsprint from a normal C++ application. But if call the same thing through a windows service (run as SYSTEM), it gives following error. It sees the printer but perhaps doesn't have access to it. I am on windows 10 but windows 7 also has the same issue. How can I solve this problem?

2006-02-24 gsprint 1.9
Couldn't open Windows GDI printer driver
Requested printer: "SupplyDep"

Available printers:
"Send to OneNote 2010"
"VirtualPrinter"
"SupplyDep"
"Microsoft XPS Document Writer"
"Fax"

答:
I ran into a similar issue trying to run gsprint as the NT Authority/system user.  The last post in this link helped a lot.  Basically I setup the printer under my user and then I copied the registry entries for the printer to the default user.

```<code>Below are the registry keys I copied from HKEY_CURRENT_USER to HKEY_USERS\.DEFAULT

    HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices
    HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts
    HKEY_CURRENT_USER\Printers
</code>```

You'll need to restart the Print Spooler service (or just restart the server) in order for the changes to take effect.

Body:
I ran into a similar issue trying to run gsprint as the NT Authority/system user.  The last post in this link helped a lot.  Basically I setup the printer under my user and then I copied the registry entries for the printer to the default user.

Below are the registry keys I copied from HKEY_CURRENT_USER to HKEY_USERS\.DEFAULT

    HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices
    HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts
    HKEY_CURRENT_USER\Printers

You'll need to restart the Print Spooler service (or just restart the server) in order for the changes to take effect.