问:
Html: The page footer and a long form get overlapped
I am using a ready-made template as my css/html skills are very humble and I am more comfortable with backend development.

This is the pre-defined login page:

In the register-page (which contains many more fields) that I created based on the pre-defined login page:

Notice how the footer get mixed-up with the form.

This is the html code:

```<code> <>
      <ExamplesNavbar />
      <div
        className="page-header"
        style={{
          backgroundImage: "url(" + require("assets/img/login-image.jpg") + ")",
        }}
      >
        <div className="filter" />
        <Container>
          <Row>
            <Col className="ml-auto mr-auto" lg="4">
              <Card className="card-register ml-auto mr-auto">
                <h3 className="title mx-auto">Welcome</h3>
                <div className="social-line text-center">
                  <Button
                    className="btn-neutral btn-just-icon mr-1"
                    color="facebook"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    <i className="fa fa-facebook-square" />
                  </Button>
                  <Button
                    className="btn-neutral btn-just-icon mr-1"
                    color="google"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    <i className="fa fa-google-plus" />
                  </Button>
                  <Button
                    className="btn-neutral btn-just-icon"
                    color="twitter"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    <i className="fa fa-twitter" />
                  </Button>
                </div>
                <Form className="register-form">
                  <label>First name</label>
                  <Input placeholder="First name" type="text" />
                  <label>Surname</label>
                  <Input placeholder="Surname" type="text" />
                  <label>Email</label>
                  <Input placeholder="Email" type="text" />
                  <label>Password</label>
                  <Input placeholder="Password" type="password" />
                  <label>Confirm password</label>
                  <Input placeholder="Password" type="password" />
                  <label>Birthday</label>
                  <Input placeholder="date placeholder" type="date" />
                  <label>Country</label>
                  <CountryDropdown
                    style={{ width: "100%" }}
                    value={"Tunisia"}
                    // onChange={(val) => this.selectCountry(val)}
                  />
                  <Button block className="btn-round" color="danger">
                    Login
                  </Button>
                </Form>
                <div className="forgot">
                  <Button
                    className="btn-link"
                    color="danger"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    Forgot password?
                  </Button>
                </div>
              </Card>
            </Col>
          </Row>
        </Container>
        <div className="footer register-footer text-center">
          <h6>
            © {new Date().getFullYear()}, made with{" "}
            <i className="fa fa-heart heart" /> by Creative Tim
          </h6>
        </div>
      </div>
    </>
</code>```

I'm a bit suprised this happens since I've never seen html elements overlapping. But as I said my front-end skills and knoweldge is still being built-up. So if anyone could offer an explanation/solution for this, I'd be more than grateful.

NOTE: This is built using Reactstrap.

答:
For some reason when I changed the react code from a function component to a stateful component, the problem disapeared:

```<code>function RegisterPage() {
  document.documentElement.classList.remove("nav-open");
  React.useEffect(() => {
    document.body.classList.add("register-page");
    return function cleanup() {
      document.body.classList.remove("register-page");
    };
  });
  return (
    <>
      <ExamplesNavbar />
      <div
        className="page-header"
        style={{
          backgroundImage: "url(" + require("assets/img/login-image.jpg") + ")",
        }}
      >
        <div className="filter" />
        <Container>
          <Row>
            <Col className="ml-auto mr-auto" lg="4">
              <Card className="card-register ml-auto mr-auto">
                <h3 className="title mx-auto">Welcome</h3>
                <div className="social-line text-center">
                  <Button
                    className="btn-neutral btn-just-icon mr-1"
                    color="facebook"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    <i className="fa fa-facebook-square" />
                  </Button>
                  <Button
                    className="btn-neutral btn-just-icon mr-1"
                    color="google"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    <i className="fa fa-google-plus" />
                  </Button>
                  <Button
                    className="btn-neutral btn-just-icon"
                    color="twitter"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    <i className="fa fa-twitter" />
                  </Button>
                </div>
                <Form className="register-form">
                  <label>First name</label>
                  <Input
                    placeholder="First name"
                    type="text"
                    onChange={(e) => {
                      console.log(e.target.value);
                    }}
                  />
                  <label>Surname</label>
                  <Input placeholder="Surname" type="text" />
                  <label>Email</label>
                  <Input placeholder="Email" type="text" />
                  <label>Password</label>
                  <Input placeholder="Password" type="password" />
                  <label>Confirm password</label>
                  <Input placeholder="Password" type="password" />
                  <label>Birthday</label>
                  <Input placeholder="date placeholder" type="date" />
                  <label>Country</label>
                  <CountryDropdown
                    style={{ width: "100%" }}
                    value={"Tunisia"}
                    // onChange={(val) => this.selectCountry(val)}
                  />
                  <Button block className="btn-round" color="danger">
                    Login
                  </Button>
                </Form>
                <div className="forgot">
                  <Button
                    className="btn-link"
                    color="danger"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    Forgot password?
                  </Button>
                </div>
              </Card>
            </Col>
          </Row>
        </Container>
        <div className="footer register-footer text-center">
          <h6>
            © {new Date().getFullYear()}, made with{" "}
            <i className="fa fa-heart heart" /> by Creative Tim
          </h6>
        </div>
      </div>
    </>
  );
}
</code>```

To this:

```<code>export class RegisterPage extends Component {
  constructor() {
    super();
    this.state = {
      email: "",
    };
  }

  render() {
    return (
      <>
        <ExamplesNavbar />
        <div
          className="page-header"
          style={{
            backgroundImage:
              "url(" + require("assets/img/login-image.jpg") + ")",
          }}
        >
          <div className="filter" />
          <Container>
            <Row>
              <Col className="ml-auto mr-auto" lg="4">
                <Card className="card-register ml-auto mr-auto">
                  <h3 className="title mx-auto">Welcome</h3>
                  <div className="social-line text-center">
                    <Button
                      className="btn-neutral btn-just-icon mr-1"
                      color="facebook"
                      href="#pablo"
                      onClick={(e) => e.preventDefault()}
                    >
                      <i className="fa fa-facebook-square" />
                    </Button>
                    <Button
                      className="btn-neutral btn-just-icon mr-1"
                      color="google"
                      href="#pablo"
                      onClick={(e) => e.preventDefault()}
                    >
                      <i className="fa fa-google-plus" />
                    </Button>
                    <Button
                      className="btn-neutral btn-just-icon"
                      color="twitter"
                      href="#pablo"
                      onClick={(e) => e.preventDefault()}
                    >
                      <i className="fa fa-twitter" />
                    </Button>
                  </div>
                  <Form className="register-form">
                    <label>First name</label>
                    <Input
                      placeholder="First name"
                      type="text"
                      onChange={(e) => {
                        console.log(e.target.value);
                      }}
                    />
                    <label>Surname</label>
                    <Input placeholder="Surname" type="text" />
                    <label>Email</label>
                    <Input placeholder="Email" type="text" />
                    <label>Password</label>
                    <Input placeholder="Password" type="password" />
                    <label>Confirm password</label>
                    <Input placeholder="Password" type="password" />
                    <label>Birthday</label>
                    <Input placeholder="date placeholder" type="date" />
                    <label>Country</label>
                    <CountryDropdown
                      style={{ width: "100%" }}
                      value={"Tunisia"}
                      // onChange={(val) => this.selectCountry(val)}
                    />
                    <Button block className="btn-round" color="danger">
                      Login
                    </Button>
                  </Form>
                  <div className="forgot">
                    <Button
                      className="btn-link"
                      color="danger"
                      href="#pablo"
                      onClick={(e) => e.preventDefault()}
                    >
                      Forgot password?
                    </Button>
                  </div>
                </Card>
              </Col>
            </Row>
          </Container>
          <div className="footer register-footer text-center">
            <h6>
              © {new Date().getFullYear()}, made with{" "}
              <i className="fa fa-heart heart" /> by Creative Tim
            </h6>
          </div>
        </div>
      </>
    );
  }
}
</code>```

Body:
I am using a ready-made template as my css/html skills are very humble and I am more comfortable with backend development.

This is the pre-defined login page:

In the register-page (which contains many more fields) that I created based on the pre-defined login page:

Notice how the footer get mixed-up with the form.

This is the html code:

 <>
      <ExamplesNavbar />

        <Container>
          <Row>
            <Col className="ml-auto mr-auto" lg="4">
              <Card className="card-register ml-auto mr-auto">

Welcome

                  <Button
                    className="btn-neutral btn-just-icon mr-1"
                    color="facebook"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >

                  </Button>
                  <Button
                    className="btn-neutral btn-just-icon mr-1"
                    color="google"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >

                  </Button>
                  <Button
                    className="btn-neutral btn-just-icon"
                    color="twitter"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >

                  </Button>

                <Form className="register-form">
                  First name
                  <Input placeholder="First name" type="text" />
                  Surname
                  <Input placeholder="Surname" type="text" />
                  Email
                  <Input placeholder="Email" type="text" />
                  Password
                  <Input placeholder="Password" type="password" />
                  Confirm password
                  <Input placeholder="Password" type="password" />
                  Birthday
                  <Input placeholder="date placeholder" type="date" />
                  Country
                  <CountryDropdown
                    style={{ width: "100%" }}
                    value={"Tunisia"}
                    // onChange={(val) => this.selectCountry(val)}
                  />
                  <Button block className="btn-round" color="danger">
                    Login
                  </Button>
                </Form>

                  <Button
                    className="btn-link"
                    color="danger"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    Forgot password?
                  </Button>

              </Card>
            </Col>
          </Row>
        </Container>

            © {new Date().getFullYear()}, made with{" "}
             by Creative Tim

    </>

I'm a bit suprised this happens since I've never seen html elements overlapping. But as I said my front-end skills and knoweldge is still being built-up. So if anyone could offer an explanation/solution for this, I'd be more than grateful.

NOTE: This is built using Reactstrap.

Body:
For some reason when I changed the react code from a function component to a stateful component, the problem disapeared:

function RegisterPage() {
  document.documentElement.classList.remove("nav-open");
  React.useEffect(() => {
    document.body.classList.add("register-page");
    return function cleanup() {
      document.body.classList.remove("register-page");
    };
  });
  return (
    <>
      <ExamplesNavbar />
      <div
        className="page-header"
        style={{
          backgroundImage: "url(" + require("assets/img/login-image.jpg") + ")",
        }}
      >
        <div className="filter" />
        <Container>
          <Row>
            <Col className="ml-auto mr-auto" lg="4">
              <Card className="card-register ml-auto mr-auto">
                <h3 className="title mx-auto">Welcome</h3>
                <div className="social-line text-center">
                  <Button
                    className="btn-neutral btn-just-icon mr-1"
                    color="facebook"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    <i className="fa fa-facebook-square" />
                  </Button>
                  <Button
                    className="btn-neutral btn-just-icon mr-1"
                    color="google"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    <i className="fa fa-google-plus" />
                  </Button>
                  <Button
                    className="btn-neutral btn-just-icon"
                    color="twitter"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    <i className="fa fa-twitter" />
                  </Button>
                </div>
                <Form className="register-form">
                  <label>First name</label>
                  <Input
                    placeholder="First name"
                    type="text"
                    onChange={(e) => {
                      console.log(e.target.value);
                    }}
                  />
                  <label>Surname</label>
                  <Input placeholder="Surname" type="text" />
                  <label>Email</label>
                  <Input placeholder="Email" type="text" />
                  <label>Password</label>
                  <Input placeholder="Password" type="password" />
                  <label>Confirm password</label>
                  <Input placeholder="Password" type="password" />
                  <label>Birthday</label>
                  <Input placeholder="date placeholder" type="date" />
                  <label>Country</label>
                  <CountryDropdown
                    style={{ width: "100%" }}
                    value={"Tunisia"}
                    // onChange={(val) => this.selectCountry(val)}
                  />
                  <Button block className="btn-round" color="danger">
                    Login
                  </Button>
                </Form>
                <div className="forgot">
                  <Button
                    className="btn-link"
                    color="danger"
                    href="#pablo"
                    onClick={(e) => e.preventDefault()}
                  >
                    Forgot password?
                  </Button>
                </div>
              </Card>
            </Col>
          </Row>
        </Container>
        <div className="footer register-footer text-center">
          <h6>
            © {new Date().getFullYear()}, made with{" "}
            <i className="fa fa-heart heart" /> by Creative Tim
          </h6>
        </div>
      </div>
    </>
  );
}

To this:

export class RegisterPage extends Component {
  constructor() {
    super();
    this.state = {
      email: "",
    };
  }

  render() {
    return (
      <>
        <ExamplesNavbar />
        <div
          className="page-header"
          style={{
            backgroundImage:
              "url(" + require("assets/img/login-image.jpg") + ")",
          }}
        >
          <div className="filter" />
          <Container>
            <Row>
              <Col className="ml-auto mr-auto" lg="4">
                <Card className="card-register ml-auto mr-auto">
                  <h3 className="title mx-auto">Welcome</h3>
                  <div className="social-line text-center">
                    <Button
                      className="btn-neutral btn-just-icon mr-1"
                      color="facebook"
                      href="#pablo"
                      onClick={(e) => e.preventDefault()}
                    >
                      <i className="fa fa-facebook-square" />
                    </Button>
                    <Button
                      className="btn-neutral btn-just-icon mr-1"
                      color="google"
                      href="#pablo"
                      onClick={(e) => e.preventDefault()}
                    >
                      <i className="fa fa-google-plus" />
                    </Button>
                    <Button
                      className="btn-neutral btn-just-icon"
                      color="twitter"
                      href="#pablo"
                      onClick={(e) => e.preventDefault()}
                    >
                      <i className="fa fa-twitter" />
                    </Button>
                  </div>
                  <Form className="register-form">
                    <label>First name</label>
                    <Input
                      placeholder="First name"
                      type="text"
                      onChange={(e) => {
                        console.log(e.target.value);
                      }}
                    />
                    <label>Surname</label>
                    <Input placeholder="Surname" type="text" />
                    <label>Email</label>
                    <Input placeholder="Email" type="text" />
                    <label>Password</label>
                    <Input placeholder="Password" type="password" />
                    <label>Confirm password</label>
                    <Input placeholder="Password" type="password" />
                    <label>Birthday</label>
                    <Input placeholder="date placeholder" type="date" />
                    <label>Country</label>
                    <CountryDropdown
                      style={{ width: "100%" }}
                      value={"Tunisia"}
                      // onChange={(val) => this.selectCountry(val)}
                    />
                    <Button block className="btn-round" color="danger">
                      Login
                    </Button>
                  </Form>
                  <div className="forgot">
                    <Button
                      className="btn-link"
                      color="danger"
                      href="#pablo"
                      onClick={(e) => e.preventDefault()}
                    >
                      Forgot password?
                    </Button>
                  </div>
                </Card>
              </Col>
            </Row>
          </Container>
          <div className="footer register-footer text-center">
            <h6>
              © {new Date().getFullYear()}, made with{" "}
              <i className="fa fa-heart heart" /> by Creative Tim
            </h6>
          </div>
        </div>
      </>
    );
  }
}


来源: stackexchange

问:
Adding image to a message does not work when replying to a message
I am trying to get an image attached to a message which is a replay.

msg.reply(JSON.parse(data).results[0].overview, { file : JSON.parse(data).results[0].poster_path});
```

but only the "overview" which is a string get sent, without the "poster_path" image.

Why is that and how can I fix it?

I have checked and the JSON data is valid.

答:
To make your code clearer and avoid memory overload, you can call this once

   // get first value
   var firstResult = JSON.parse(data).results[0];

   // confirm the result
   console.log(firstResult);

   // action
   msg.reply(firstResult.overview, { file : firstResult.poster_path});

```

try view firstResult in the console to confirm the response.

ContentLicense: CC BY-SA 4.0

Body:
I am trying to get an image attached to a message which is a replay.

msg.reply(JSON.parse(data).results[0].overview, { file : JSON.parse(data).results[0].poster_path});

but only the "overview" which is a string get sent, without the "poster_path" image.

Why is that and how can I fix it?

I have checked and the JSON data is valid.

Body:
To make your code clearer and avoid memory overload, you can call this once

   // get first value
   var firstResult = JSON.parse(data).results[0];

   // confirm the result
   console.log(firstResult);

   // action
   msg.reply(firstResult.overview, { file : firstResult.poster_path});

try view firstResult in the console to confirm the response.


问:
How to properly combine Firestore search with infinite scroll?
After watching and reading a number of tutorials, I have a solution that allows me to have a list of products on a page and limits the number displayed, increasing as the user scrolls, to prevent exessive reads. This works as expected.

I have since attempted to expand the functionality of this page to allow a user to search through the products using 'array-contains', with each product having an array of keywords that is used as the 'search term'. Again, this feature works... but only when not combined with the ininfite scroll.

My issue is I am struggling to find the correct way to combine the functionality of search and infinite scroll.

My current thought process is that the 'startAfter' part of my query isn't working correctly, however, I'm not 100% certain. It seems that the Observable I use to display the products on my webpage fails to reset when a search query is made.

TypeScript:

```<code>export class ProductFeedComponent implements OnInit {
  @ViewChild(CdkVirtualScrollViewport,  {static: false})
  viewport: CdkVirtualScrollViewport;

  //detects the end of the product list
  theEnd = false;

  offset = new BehaviorSubject(null);
  infinite: Observable<any[]>;
  searchText = '';

  isHandset$: Observable<boolean> = this.breakpointObserver.observe([Breakpoints.Handset])
  .pipe(
    map(result => result.matches),
    shareReplay()
  );

  constructor(private seo: SeoService, private db: AngularFirestore, private notepad: NotepadsComponent, public dialog: MatDialog, private breakpointObserver: BreakpointObserver) {
    this.searchProducts();
  }

  regularDistribution = 100 / 4 + '%';
  searchQuery: string;

  ngOnInit() {
    this.seo.generateTags({
      title: 'Product Feed',
      description: 'A catalogue filled with products.'
    });
  }

  openDialog(productName: string){
    this.dialog.open(AddToPadComponent,{
      data: {productData: productName}
    });
  }

  nextBatch(e, offset){
    //checks whether this is the end of the list
    if (this.theEnd)
    {
      return;
    }

    const end = this.viewport.getRenderedRange().end;
    const total = this.viewport.getDataLength();

    console.log(this.viewport.getDataLength());

    if (end === total)
    {
      this.offset.next(offset);
    }
  }

  searchProducts(){
    const batchMap = this.offset.pipe(
      throttleTime(500), mergeMap(n => this.getBatch(n)), scan((acc, batch) => {
        return {...acc, ...batch};
      }, {})
    );

    this.infinite = batchMap.pipe(map(v => Object.values(v)));
  }

  trackByIndex(i){
    return i;
  }

  getBatch(lastSeen: string){
    console.log('firing search...')
    console.log(lastSeen)
    const search = (<HTMLInputElement>document.getElementById("productSearch")).value;
    console.log(search);
        return this.db.collection('products', ref => ref.where('keywords', 'array-contains', search).orderBy('productName').startAfter(lastSeen).limit(batchSize))
        .snapshotChanges().pipe(tap(arr => (arr.length ? null : (this.theEnd = true))),map(arr => {
          return arr.reduce((acc, cur) => {
            const id = cur.payload.doc.id;
            console.log(id);
            const data = cur.payload.doc.data();
            console.log(data);
            return {...acc, [id]: {id, data}};
          }, {});
        })
      );
  }
}
</code>```

HTML:

```<code><input (keyup)="searchProducts()" id="productSearch" placeholder="search products...">

<ng-container *ngIf="infinite | async as products">
    <cdk-virtual-scroll-viewport itemSize="100" (scrolledIndexChange)="nextBatch($event, (products[products.length - 1].data.productName))">
        <div class="product-row" fxLayout="row wrap" fxLayout.xs="column wrap" fxFlexFill fxLayoutAlign="center center">
            <div fxFlex.gt-xs="50%" fxFlex.gt-md="30%" *cdkVirtualFor="let p of products; let i = index; trackByIndex">
                    <mat-card class="product-tile">
                        <img class="product-thumbnail" src= "{{ p.data.thumbnail }}" [routerLink]="p.id">
                        <div class="product-brand">
                            {{ p.id }}
                        </div>
                        <div class="product-details">
                            <span id="product-name">{{ p.data.productName }}</span> <span id="product-price">{{ p.data.price }}</span>
                        </div>
                        <div class="add-to-pad-button">
                            <button (click)="openDialog(p.id)" mat-raised-button color="accent">Add to Pad</button>
                            <a href="{{ p.data.link }}" class="mat-raised-button color=accent">Click Me</a>
                        </div>
                    </mat-card>
            </div>
        </div>
    </cdk-virtual-scroll-viewport>
</ng-container>
</code>```

I'm convinced I'm missing something obvious. I know that the function is being correctly as a user searches, however, I'm getting the error "Cannot read property 'data' of undefined
    at Object.eval [as handleEvent]", so something is going wrong with my query, which does not happen when nothing is being searched (e.g. when the page is initially loading).

Working example: https://www.padder.co.uk/catalogue

the two products have searchable values of 'blue' for one and 'purple' for the other. In the same 'keywords' array, which is used to retrieve products, there is a '' value, which should allow all products to show when there is no value entered in the search box, however this does not work as expected.

答:
As per site link you shared these are my observations:
You have fired search event on keyUp as you search the terms that doesn't give back any result so below line is error

```<code>        const data = cur.payload.doc.data();
</code>```

above line gives you error data of undefined.  As if i search xyz and no result is there then you get data of undefined error as it does not exists, but if you search for blue you will not get this error as you have result for that , (when response for blue query is returned).

You have to check  where the following object has a data property or not.

what you can do is

```<code>      const id = cur.payload.doc.id;

      console.log(id);

      let data = ''; // what ever value you need , or a empty object
     // check for id as, if you have result then id value will be there and then use data
    if(id){
             data = cur.payload.doc.data();
         }

-----
 // or
if(cur.payload.doc && cur.payload.doc.data){
data = cur.payload.doc.data();
}
</code>```

so you will not get error cannot read property 'data' of undefined

Also i will recommend you to add/improve a bit functionality,

1) For Search - use Debounce Time , unique value ,  start search after 2 charter typed for performance side. As right now as you hit a key it fill n/w panel with requests.

2) In template -- {{ p?.data?.productName }} -- use this as optional parameter to avoid error in case you are not sure property is there or not

Body:
After watching and reading a number of tutorials, I have a solution that allows me to have a list of products on a page and limits the number displayed, increasing as the user scrolls, to prevent exessive reads. This works as expected.

I have since attempted to expand the functionality of this page to allow a user to search through the products using 'array-contains', with each product having an array of keywords that is used as the 'search term'. Again, this feature works... but only when not combined with the ininfite scroll.

My issue is I am struggling to find the correct way to combine the functionality of search and infinite scroll.

My current thought process is that the 'startAfter' part of my query isn't working correctly, however, I'm not 100% certain. It seems that the Observable I use to display the products on my webpage fails to reset when a search query is made.

TypeScript:

export class ProductFeedComponent implements OnInit {
  @ViewChild(CdkVirtualScrollViewport,  {static: false})
  viewport: CdkVirtualScrollViewport;

  //detects the end of the product list
  theEnd = false;

  offset = new BehaviorSubject(null);
  infinite: Observable<any[]>;
  searchText = '';

  isHandset$: Observable<boolean> = this.breakpointObserver.observe([Breakpoints.Handset])
  .pipe(
    map(result => result.matches),
    shareReplay()
  );

  constructor(private seo: SeoService, private db: AngularFirestore, private notepad: NotepadsComponent, public dialog: MatDialog, private breakpointObserver: BreakpointObserver) {
    this.searchProducts();
  }

  regularDistribution = 100 / 4 + '%';
  searchQuery: string;

  ngOnInit() {
    this.seo.generateTags({
      title: 'Product Feed',
      description: 'A catalogue filled with products.'
    });
  }

  openDialog(productName: string){
    this.dialog.open(AddToPadComponent,{
      data: {productData: productName}
    });
  }

  nextBatch(e, offset){
    //checks whether this is the end of the list
    if (this.theEnd)
    {
      return;
    }

    const end = this.viewport.getRenderedRange().end;
    const total = this.viewport.getDataLength();

    console.log(this.viewport.getDataLength());

    if (end === total)
    {
      this.offset.next(offset);
    }
  }

  searchProducts(){
    const batchMap = this.offset.pipe(
      throttleTime(500), mergeMap(n => this.getBatch(n)), scan((acc, batch) => {
        return {...acc, ...batch};
      }, {})
    );

    this.infinite = batchMap.pipe(map(v => Object.values(v)));
  }

  trackByIndex(i){
    return i;
  }

  getBatch(lastSeen: string){
    console.log('firing search...')
    console.log(lastSeen)
    const search = (<HTMLInputElement>document.getElementById("productSearch")).value;
    console.log(search);
        return this.db.collection('products', ref => ref.where('keywords', 'array-contains', search).orderBy('productName').startAfter(lastSeen).limit(batchSize))
        .snapshotChanges().pipe(tap(arr => (arr.length ? null : (this.theEnd = true))),map(arr => {
          return arr.reduce((acc, cur) => {
            const id = cur.payload.doc.id;
            console.log(id);
            const data = cur.payload.doc.data();
            console.log(data);
            return {...acc, [id]: {id, data}};
          }, {});
        })
      );
  }
}

HTML:

<input (keyup)="searchProducts()" id="productSearch" placeholder="search products...">

<ng-container *ngIf="infinite | async as products">
    <cdk-virtual-scroll-viewport itemSize="100" (scrolledIndexChange)="nextBatch($event, (products[products.length - 1].data.productName))">

                    <mat-card class="product-tile">

                            {{ p.id }}

                            {{ p.data.productName }} {{ p.data.price }}

                            <button (click)="openDialog(p.id)" mat-raised-button color="accent">Add to Pad</button>
                            Click Me

                    </mat-card>

    </cdk-virtual-scroll-viewport>
</ng-container>

I'm convinced I'm missing something obvious. I know that the function is being correctly as a user searches, however, I'm getting the error "Cannot read property 'data' of undefined
    at Object.eval [as handleEvent]", so something is going wrong with my query, which does not happen when nothing is being searched (e.g. when the page is initially loading).

Working example: https://www.padder.co.uk/catalogue

the two products have searchable values of 'blue' for one and 'purple' for the other. In the same 'keywords' array, which is used to retrieve products, there is a '' value, which should allow all products to show when there is no value entered in the search box, however this does not work as expected.

Body:
As per site link you shared these are my observations:
You have fired search event on keyUp as you search the terms that doesn't give back any result so below line is error

        const data = cur.payload.doc.data();

above line gives you error data of undefined.  As if i search xyz and no result is there then you get data of undefined error as it does not exists, but if you search for blue you will not get this error as you have result for that , (when response for blue query is returned).

You have to check  where the following object has a data property or not.

what you can do is

      const id = cur.payload.doc.id;

      console.log(id);

      let data = ''; // what ever value you need , or a empty object
     // check for id as, if you have result then id value will be there and then use data
    if(id){
             data = cur.payload.doc.data();
         }

-----
 // or
if(cur.payload.doc && cur.payload.doc.data){
data = cur.payload.doc.data();
}

so you will not get error cannot read property 'data' of undefined

Also i will recommend you to add/improve a bit functionality,

1) For Search - use Debounce Time , unique value ,  start search after 2 charter typed for performance side. As right now as you hit a key it fill n/w panel with requests.

2) In template -- {{ p?.data?.productName }} -- use this as optional parameter to avoid error in case you are not sure property is there or not


问:
Angular CLI production build placing duplicates of all my fonts in the root of my dist directory. Can this be avoided?
In my Angular project, i have custom fonts stored in src/assets/fonts/*

I reference these fonts in my styles.scss file like this:

```<code>@font-face {
    font-family: 'museo_sans_package';
    src: url('assets/fonts/MuseoSans_100-webfont.eot');
...
</code>```

When doing a production build using the Angular CLI, my fonts directory along with all the font files in it are copied to my ./dist directory correctly:

./dist/assets/fonts/*

however all of my font files are also getting duplicated into the root of my /dist directory as well resulting in 2 copies of my fonts. One in ./dist/assets/fonts/* as expected, and also in ./dist/* which i do not want.

Is there a configuration i need to set somewhere to avoid this?

UPDATE: the fonts are copied to the ./dist/assets/fonts directory because the .angular-cli.json config is set to dup assets into the dist directory.

The duplication of my fonts into the root of .dist is being caused by either the sass compiler or the angular cli build process or both in that something is modifying the paths set in the urls for my @font-face rules, changing them to point to the root rather than the relative path assets/fonts/*

my current angular install:

```<code>@angular/cli: 1.1.0
node: 8.0.0
os: darwin x64
@angular/animations: 4.1.3
@angular/common: 4.1.3
@angular/compiler: 4.1.3
@angular/core: 4.1.3
@angular/forms: 4.1.3
@angular/http: 4.1.3
@angular/platform-browser: 4.1.3
@angular/platform-browser-dynamic: 4.1.3
@angular/router: 4.1.3
@angular/cli: 1.1.0
@angular/compiler-cli: 4.1.3
@angular/language-service: 4.1.3
</code>```

答:
I had the same issue and fixed it by adding an slash at the beginning of the font url like this:  </p>

```<code>src: url('/assets/fonts/MuseoSans_100-webfont.eot');
</code>```

ContentLicense: CC BY-SA 3.0

Body:
In my Angular project, i have custom fonts stored in src/assets/fonts/*

I reference these fonts in my styles.scss file like this:

@font-face {
    font-family: 'museo_sans_package';
    src: url('assets/fonts/MuseoSans_100-webfont.eot');
...

When doing a production build using the Angular CLI, my fonts directory along with all the font files in it are copied to my ./dist directory correctly:

./dist/assets/fonts/*

however all of my font files are also getting duplicated into the root of my /dist directory as well resulting in 2 copies of my fonts. One in ./dist/assets/fonts/* as expected, and also in ./dist/* which i do not want.

Is there a configuration i need to set somewhere to avoid this?

UPDATE: the fonts are copied to the ./dist/assets/fonts directory because the .angular-cli.json config is set to dup assets into the dist directory.

The duplication of my fonts into the root of .dist is being caused by either the sass compiler or the angular cli build process or both in that something is modifying the paths set in the urls for my @font-face rules, changing them to point to the root rather than the relative path assets/fonts/*

my current angular install:

@angular/cli: 1.1.0
node: 8.0.0
os: darwin x64
@angular/animations: 4.1.3
@angular/common: 4.1.3
@angular/compiler: 4.1.3
@angular/core: 4.1.3
@angular/forms: 4.1.3
@angular/http: 4.1.3
@angular/platform-browser: 4.1.3
@angular/platform-browser-dynamic: 4.1.3
@angular/router: 4.1.3
@angular/cli: 1.1.0
@angular/compiler-cli: 4.1.3
@angular/language-service: 4.1.3

Body:
I had the same issue and fixed it by adding an slash at the beginning of the font url like this:

src: url('/assets/fonts/MuseoSans_100-webfont.eot');


问:
How to break down decent-exposure code to classic Rails way?
Can anyone break this code down for me and explain how this can be done in classic Rails way with callbacks(if any) and methods?</p>

```<code>class SearchController < ApplicationController
  expose :search_result, -> { SearchService.new(search_params).call }

  def search_params
    params.permit(:q, :scope)
  end
end
</code>```

答:
```<code>class SearchController < ApplicationController
  def index
    @search_result = SearchService.new(search_params).call
  end

  def search_params
    params.permit(:q, :scope)
  end
end
</code>```

expose :search_result, -> { SearchService.new(search_params).call } creates a variable @search_result

Body:
Can anyone break this code down for me and explain how this can be done in classic Rails way with callbacks(if any) and methods?

class SearchController < ApplicationController
  expose :search_result, -> { SearchService.new(search_params).call }

  def search_params
    params.permit(:q, :scope)
  end
end

Body:
class SearchController < ApplicationController
  def index
    @search_result = SearchService.new(search_params).call
  end

  def search_params
    params.permit(:q, :scope)
  end
end

expose :search_result, -> { SearchService.new(search_params).call } creates a variable @search_result


问:
How can I check if an input is a integer or String, etc.. in JAVA?
I am wondering how I can check if a user's input is a certain primitive type (I mean integer, String, etc... I think it's called primitive type?). I want a user to input something, then I check if it's a String or not, and do a certain action accordingly. (JAVA)
I have seen some codes like this:

```<code>if (input == (String)input) { (RANDOM STUFF HERE) }
</code>```

or something like

```<code>if input.equals((String) input)
</code>```

And they don't work. I want to know how I can Check for only a String? (EDITED OUT)
I was wondering if there was a function that can do that? Thanks for the answers

EDIT: With the help of everyone I have created my fixed code that does what I want it to:

```<code>package files;
import java.util.*;
public class CheckforSomething {
static Scanner inputofUser = new Scanner(System.in);
static Object userInput;
static Object classofInput;
public static void main(String[] args){
    try{
    System.out.print("Enter an integer, only an integer: ");
    userInput = inputofUser.nextInt();

    classofInput = userInput.getClass();
    System.out.println(classofInput);
    } catch(InputMismatchException e) {
        System.out.println("Not an integer, crashing down");

    }

 }

 }
</code>```

No need for answers anymore, thanks!

答:
Hate to bring this up after 6 years but I found another possible solution.

Currently attending a coding bootcamp and had to solve a similar problem. We introduce booleans and change their values depending on the result of the try/catch blocks. We then check the booleans using simple if statements. You can omit the prints and input your code instead. Here's what it looks like:

```<code>import java.io.IOException;
import java.util.Scanner;

public class DataTypeFinder {
    public static void main(String[] args) throws IOException {
        Scanner scan = new Scanner(System.in);
        String input = "";

        while (true) { //so we can check multiple inputs (optional)
            input = scan.nextLine();

            if ("END".equals(input)) { //a way to exit the loop
                break;
            }

            boolean isInt = true; //introduce boolean to check if input is of type Integer
            try { // surround with try/catch
                int integer = Integer.parseInt(input); //boolean is still true if it works
            } catch (NumberFormatException e) {
                isInt = false; //changed to false if it doesn't
            }

            boolean isDouble = true; //same story
            try {
                double dbl = Double.parseDouble(input);
            } catch (NumberFormatException e) {
                isDouble = false;
            }

            if (isInt) {
                System.out.printf("%s is integer type%n", input);
            } else if (isDouble) {
                System.out.printf("%s is floating point type%n", input);
            } else if (input.length() == 1) { //this could be useless depending on your case
                System.out.printf("%s is character type%n", input);
            } else if ("true".equals(input.toLowerCase()) || "false".equals(input.toLowerCase())) {
                System.out.printf("%s is boolean type%n", input);
            } else {
                System.out.printf("%s is string type%n", input);
            }
        }
    }
}
</code>```

Body:
I am wondering how I can check if a user's input is a certain primitive type (I mean integer, String, etc... I think it's called primitive type?). I want a user to input something, then I check if it's a String or not, and do a certain action accordingly. (JAVA)
I have seen some codes like this:

if (input == (String)input) { (RANDOM STUFF HERE) }

or something like

if input.equals((String) input)

And they don't work. I want to know how I can Check for only a String? (EDITED OUT)
I was wondering if there was a function that can do that? Thanks for the answers

EDIT: With the help of everyone I have created my fixed code that does what I want it to:

package files;
import java.util.*;
public class CheckforSomething {
static Scanner inputofUser = new Scanner(System.in);
static Object userInput;
static Object classofInput;
public static void main(String[] args){
    try{
    System.out.print("Enter an integer, only an integer: ");
    userInput = inputofUser.nextInt();

    classofInput = userInput.getClass();
    System.out.println(classofInput);
    } catch(InputMismatchException e) {
        System.out.println("Not an integer, crashing down");

    }

 }

 }

No need for answers anymore, thanks!

Body:
Hate to bring this up after 6 years but I found another possible solution.

Currently attending a coding bootcamp and had to solve a similar problem. We introduce booleans and change their values depending on the result of the try/catch blocks. We then check the booleans using simple if statements. You can omit the prints and input your code instead. Here's what it looks like:

import java.io.IOException;
import java.util.Scanner;

public class DataTypeFinder {
    public static void main(String[] args) throws IOException {
        Scanner scan = new Scanner(System.in);
        String input = "";

        while (true) { //so we can check multiple inputs (optional)
            input = scan.nextLine();

            if ("END".equals(input)) { //a way to exit the loop
                break;
            }

            boolean isInt = true; //introduce boolean to check if input is of type Integer
            try { // surround with try/catch
                int integer = Integer.parseInt(input); //boolean is still true if it works
            } catch (NumberFormatException e) {
                isInt = false; //changed to false if it doesn't
            }

            boolean isDouble = true; //same story
            try {
                double dbl = Double.parseDouble(input);
            } catch (NumberFormatException e) {
                isDouble = false;
            }

            if (isInt) {
                System.out.printf("%s is integer type%n", input);
            } else if (isDouble) {
                System.out.printf("%s is floating point type%n", input);
            } else if (input.length() == 1) { //this could be useless depending on your case
                System.out.printf("%s is character type%n", input);
            } else if ("true".equals(input.toLowerCase()) || "false".equals(input.toLowerCase())) {
                System.out.printf("%s is boolean type%n", input);
            } else {
                System.out.printf("%s is string type%n", input);
            }
        }
    }
}


问:
What is the tidiest way to add a legend to ggplot with multiple geom_step?
I consider the following plot.

```<code>d=data.frame(x=c(1,2,4,5,7,8,9), y=c(0,2,3,5,6,7,9))
d2=data.frame(x=c(1,2,3.5,7.2,9), y=c(0,3,7,1.5,4))
ggplot() + geom_step(data=d, mapping=aes(x=x, y=y)) + geom_step(data=d2, mapping=aes(x=x, y=y), color=2)
</code>```

We have a plot with multiple (here two) step functions that have different number and location of change points on x. So I cannot directly add them to the same data.frame without more data manipulation. What would be the best option to add a legend to this plot?

答:
I may have completely misunderstood the question, but I don't fully understand what the problem of a classic "making long" approach is?

The different x do not matter. Internally, the geom calculates the statistics for each group defined by aes, kind of creating n different data sets from your data. IMO, this is the "most ggplot-y" way, because it makes use of the advantages of mapping a variable to an aesthetic.

library(tidyverse)
d <- data.frame(x = c(1, 2, 4, 5, 7, 8, 9), y = c(0, 2, 3, 5, 6, 7, 9))
d2 <- data.frame(x = c(1, 2, 3.5, 7.2, 9), y = c(0, 3, 7, 1.5, 4))

d_bind <- bind_rows(list(d = d, d2 = d2), .id = "id")

ggplot() +
  geom_step(data = d_bind, mapping = aes(x = x, y = y, color = id)) +
  scale_color_manual(values = c(d = "black", d2 = "red"))
```

Body:
I consider the following plot.

d=data.frame(x=c(1,2,4,5,7,8,9), y=c(0,2,3,5,6,7,9))
d2=data.frame(x=c(1,2,3.5,7.2,9), y=c(0,3,7,1.5,4))
ggplot() + geom_step(data=d, mapping=aes(x=x, y=y)) + geom_step(data=d2, mapping=aes(x=x, y=y), color=2)

We have a plot with multiple (here two) step functions that have different number and location of change points on x. So I cannot directly add them to the same data.frame without more data manipulation. What would be the best option to add a legend to this plot?


问:
Failed to override styles with classes in material-ui
I was implementing a table with TableRow component from material-ui, which has a property called "selected". Whenever "selected" is true, a pink background-color(from the default theme) is applied for it.
I was trying to change this default pink color, according to the docs, i chose to override the css classes like:

```<code>const styles = theme => ({
  rowSelected: {
    backgroundColor: theme.palette.grey[700]
  }
})
class CustomTableRow extends React.Component {
// basic component logic
render() {
const {classes, className, style } = this.props;
  <TableRow
    key={key}
    component="div"
    selected={true}
    hover={true}
    className={className}
    classes={{ selected: classes.rowSelected}}
    style={style}
  >
      // some children
  </TableRow>
}
export default withStyles(styles, { withTheme: true })(CustomTableRow);

</code>```

But this didn't work, which was very confusing. Because i had succeeded to do the same thing somewhere else for a Drawer component with the same method above.

I debugged every css properties with Chrome Dev Tools. What i am suspecting most now is, the pink color applied on this component with this way below:

```<code>.MuiTableRow-root.Mui-selected, .MuiTableRow-root.Mui-selected:hover {
    background-color: rgba(245, 0, 87, 0.16);
</code>```

And my custom class style had lower precedence than this one, which was greyed out.

UPDATE1:

My project is too big, i don't know how to simplify it for codesandbox.io.
Maybe we can check the material-ui source code directly, TableRow Source Code.
What i was doing is to override this css declaration in root

```<code>    '&$selected, &$selected:hover': {
      backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.selectedOpacity),
    },
</code>```

by passing in another selected declaration below. I realized it's because this &$selected, &$selected:hover is not normally css, even if i copy this into rowSelected, it doesn't work either.

UPDATE2:

I managed to override that backgroundColor, with '!important' keyword:

```<code>const styles = theme => ({
  rowSelected: {
    backgroundColor: theme.palette.grey[700] + " !important",
  }
})
</code>```

I don't know whether this is one ideal solution. This clearly shows the problem is about css classes precedence. So how to override that already defined backgroundColor in class root with class selected.

Some help please, thank you.

答:
To provide specifity for selected class you can apply the $selected and $selected:hover classes to your overrides like below

```<code>const styles = theme => ({
  rowSelected: {
    "&$selected, &$selected:hover": {
      backgroundColor: theme.palette.grey[800]
    }
  }
})
</code>```

Sample demo

Body:
I was implementing a table with TableRow component from material-ui, which has a property called "selected". Whenever "selected" is true, a pink background-color(from the default theme) is applied for it.
I was trying to change this default pink color, according to the docs, i chose to override the css classes like:

const styles = theme => ({
  rowSelected: {
    backgroundColor: theme.palette.grey[700]
  }
})
class CustomTableRow extends React.Component {
// basic component logic
render() {
const {classes, className, style } = this.props;
  <TableRow
    key={key}
    component="div"
    selected={true}
    hover={true}
    className={className}
    classes={{ selected: classes.rowSelected}}
    style={style}
  >
      // some children
  </TableRow>
}
export default withStyles(styles, { withTheme: true })(CustomTableRow);

But this didn't work, which was very confusing. Because i had succeeded to do the same thing somewhere else for a Drawer component with the same method above.

I debugged every css properties with Chrome Dev Tools. What i am suspecting most now is, the pink color applied on this component with this way below:

.MuiTableRow-root.Mui-selected, .MuiTableRow-root.Mui-selected:hover {
    background-color: rgba(245, 0, 87, 0.16);

And my custom class style had lower precedence than this one, which was greyed out.

UPDATE1:

My project is too big, i don't know how to simplify it for codesandbox.io.
Maybe we can check the material-ui source code directly, TableRow Source Code.
What i was doing is to override this css declaration in root

    '&$selected, &$selected:hover': {
      backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.selectedOpacity),
    },

by passing in another selected declaration below. I realized it's because this &$selected, &$selected:hover is not normally css, even if i copy this into rowSelected, it doesn't work either.

UPDATE2:

I managed to override that backgroundColor, with '!important' keyword:

const styles = theme => ({
  rowSelected: {
    backgroundColor: theme.palette.grey[700] + " !important",
  }
})

I don't know whether this is one ideal solution. This clearly shows the problem is about css classes precedence. So how to override that already defined backgroundColor in class root with class selected.

Some help please, thank you.

Body:
To provide specifity for selected class you can apply the $selected and $selected:hover classes to your overrides like below

const styles = theme => ({
  rowSelected: {
    "&$selected, &$selected:hover": {
      backgroundColor: theme.palette.grey[800]
    }
  }
})

Sample demo


问:
Which design pattern to use when we have classes that does similar high level functionality but the returns different types in methods?
I have an existing C# console application that takes arguments and based on the arguments
creates an instance of markets (UK, US, MX..) using dependency injection.

Each market class does a 'string GetData()', 'string  ProcessData()' and 'bool ExportData()'.

The application was initially created for one eCommerce vendor's markets. Now I am told to modify it for a different vendor that does a different process. The high-level flow remains the same.

'GetData' to fetch records from DB,

'ProcessData' for any transformation or the likes

'ExportData'.

The difference is Getdata() pulls records from DB and maps to an object. I am planning to use Petapoco. 'ProcessData' might return a similar class. 'Exportdata' currently does an API call but for the new vendor, I have to write to a file.

I was reading up on patterns I am totally confused. At first, I thought I needed abstract factory pattern and now I think the factory method is what I should be using but I am not sure if I am doing it right. Need some guidance/review here. A sample cs file I created from my understanding of factory pattern. This code is based on the headfirst code samples.

```<code>using System;
using System.Collections.Generic;
using StatusExport.Models;

namespace factorymethod
{
    class Program
    {
        static void Main(string[] args)
        {
            ClientFactory factory = null;
            Console.WriteLine("Enter client code:");
            string clientCode= Console.ReadLine();
            switch (clientCode.ToLower())
            {
                case "costco":
                    factory = new CostcoFactory("accountname", "taskname");
                    break;
                    //NEw vendor might be added
                    //case "walmart"
                    //factory = new WalmartFactory("taskname", "type");
                    //break
                default:
                    break;
            }

            bool status = factory.ProcessData();
            Console.ReadKey();
        }
    }

    abstract class Client
    {
        public abstract string AccountName { get; }
        public abstract string Task { get; set; }
        //More properties might be added. Some may not even be used by some of the new vendors. For example, Costco Might need accountname and task. Tomorrow if walmart comes, they might not need these two or may need task and a new property 'type'
        public abstract List<T> GetData<T>();
        public abstract List<T> ProcessData<T>();
        public abstract bool ExportData();
    }

    class CostcoClient : Client
    {
        public override string AccountName { get; }
        public override string Task { get; set; }

        public CostcoClient(string accountName, string task)
        {
            AccountName = accountName;
            Task = task;
        }

        public override List<DBRecord> GetData<DBRecord>() //DBRecord class is specific to Costco.
        {
            List<DBRecord> dbresult = new List<DBRecord>();
            //dbresult = db return data mapped to an object DBRecord using petapoco. Another vendor might have a different class to which DB records are mapped. So the return type can be generic
            return asn;
        }

        public override List<T> ProcessData<T>()
        {
            throw new NotImplementedException(); //Any data transformation or business logic. Return type might be DBRecord or a new class altogether
        }

        public override bool ExportData()
        {
            throw new NotImplementedException();//Call API or write data to file and if success send true else false
        }
    }

    abstract class ClientFactory
    {
        public abstract bool ProcessData();
    }

    class CostcoFactory : ClientFactory
    {
        public string AccountName { get; }
        public string Task { get; set; }
        public CostcoFactory(string accountname, string task)
        {
            AccountName = accountname;
            Task = task;
        }

        public override bool ProcessData()
        {
            CostcoClient gc = new CostcoClient(AccountName, Task);
            var result = gc.GetData<DBRecord>();
            return true;
        }
    }
}
</code>```

Do you think this is the right design approach?

I also want to keep the console project independent of vendor project. So maybe 'StatusExport.Program' for the console application. DLL projects StatusExport.Common to hold the interface and abstract classes' and 'StatusExport.Client(ex:StatusExport.Costco)' for each vendor stuff.

答:
You can create BaseClient class that will contains a basic group of properties, and if you need to add something new - just inherit it. You did right, but i think it's better to change public modifier to protected in your properties AccountName and Task, to give access to them only from child classes.
Actually, you can create a BaseClientModels (request/response) for each method if you are not sure that returning type List will be always actual.
Example:

```<code>public abstract class BaseClient
{
    #region Properties : Protected

    protected abstract string AccountName { get; }

    protected abstract string Task { get; set; }

    #endregion

    #region Methods : Public

    public abstract BaseGetDataResponseModel GetData(BaseGetDataRequestModel model);

    public abstract BaseProcessDataResponseModel ProcessData(BaseProcessDataRequestModel model);

    public abstract BaseExportDataResponseModel ExportData(BaseExportDataRequestModel model);

    #endregion
}

public class BaseGetDataResponseModel { }

public class BaseGetDataRequestModel { }

public class BaseProcessDataResponseModel { }

public class BaseProcessDataRequestModel { }

public class BaseExportDataResponseModel { }

public class BaseExportDataRequestModel { }
</code>```

Then let's look on your class CostcoClient and how it can looks like:

```<code>public class CostcoClient : BaseClient
{
    #region Properties : Protected

    protected override string AccountName { get; }

    protected override string Task { get; set; }

    protected virtual IDataReader<BaseGetDataRequestModel, BaseGetDataResponseModel> DataReader { get; }

    protected virtual IDataProcessor<CostcoClientProcessDataRequestModel, CostcoClientProcessDataResponseModel> DataProcessor { get; }

    protected virtual IExportDataHandler<CostcoClientExportDataRequestModel, CostcoClientExportDataResponseModel> ExportDataHandler { get; }

    #endregion

    #region Constructors

    public CostcoClient(string accountName, string task)
    {
//set DataReader, DataProcessor, ExportDataHandler
        AccountName = accountName;
        Task = task;
    }

    #endregion

    #region Methods : Public

    public override BaseGetDataResponseModel GetData(BaseGetDataRequestModel model)
    {
        if (model is CostcoClientGetDataRequestModel clientGetDataRequestModel)
        {
            return DataReader.ReadData(clientGetDataRequestModel);
        }
        return null; //wrong type has passed
    }

    public override BaseProcessDataResponseModel ProcessData(BaseProcessDataRequestModel model)
    {
        if (model is CostcoClientProcessDataRequestModel clientProcessDataRequestModel)
        {
            return DataProcessor.ProcessData(clientProcessDataRequestModel);
        }
        return null;
    }

    public override BaseExportDataResponseModel ExportData(BaseExportDataRequestModel model)
    {
        if (model is CostcoClientExportDataRequestModel clientExportDataRequestModel)
        {
            return ExportDataHandler.Handle(clientExportDataRequestModel);
        }
        return null;
    }

    #endregion
}

public class CostcoClientGetDataRequestModel : BaseGetDataRequestModel { }

public class CostcoClientGetDataResponseModel : BaseGetDataResponseModel { }

public class CostcoClientProcessDataRequestModel : BaseProcessDataRequestModel { }

public class CostcoClientProcessDataResponseModel : BaseProcessDataResponseModel { }

public class CostcoClientExportDataRequestModel : BaseExportDataRequestModel { }

public class CostcoClientExportDataResponseModel : BaseExportDataResponseModel { }

public interface IDataReader<TIn, TOut>
{
    public TOut ReadData(TIn model);
}

public interface IDataProcessor<TIn, TOut>
{
    public TOut ProcessData(TIn model);
}

public interface IExportDataHandler<TIn, TOut>
{
    public TOut Handle(TIn model);
}

public class CostcoClientDataReader : IDataReader<CostcoClientGetDataRequestModel, CostcoClientGetDataResponseModel>
{
    public CostcoClientGetDataResponseModel ReadData(CostcoClientGetDataRequestModel model)
    {
        throw new NotImplementedException();
    }
}

    //and so on
</code>```

You have to implement IDataReader, IDataProcessor, IExportDataHandler, make your logic and call it from GetData, ProcessData, ExportData methods, as an example, and get instances via dependency injection.

Then, we can change your factory to this:

```<code>public interface IClientFactory
{
    BaseClient GetClientService(ClientServicesEnum value);
}

public class BaseClientFactory : IClientFactory
{
    #region Propertied : Protected

    protected virtual IEnumerable<BaseClient> Services { get; }

    protected string AccountName { get; }

    protected string Task { get; set; }

    #endregion

    #region Constructors

    public BaseClientFactory(IEnumerable<BaseClient> services, string accountname, string task)
    {
        Services = services;
        AccountName = accountname;
        Task = task;
    }

    #endregion

    public BaseClient GetClientService(ClientServicesEnum value)
        => Services.First(x => x.GetType().Equals(GetClientServiceByCode()[value]));

    private Dictionary<ClientServicesEnum, Type> GetClientServiceByCode()
        => new Dictionary<ClientServicesEnum, Type>()
        {
            { ClientServicesEnum.CostcoClient, typeof(CostcoClient) }
        };

}

public enum ClientServicesEnum
{
    CostcoClient = 1,
    Another2 = 2,
    Another3 = 3
}
</code>```

Where

```<code>protected virtual IEnumerable<BaseClient> Services { get; }
</code>```

you can get via DI too, and then get correct ServiceHandler by enum.

And your main function to call all this:

```<code>        switch (clientCode)
        {
            case 1:
                baseClient = ClientFactory.GetClientService(ClientServicesEnum.CostcoClient);
                break;
            case 2:
                baseClient = ClientFactory.GetClientService(ClientServicesEnum.Another2);
                break;
            default:
                break;
        }

        bool status = baseClient.ProcessData(null); //your model
</code>```

The main thing is - you can use more than one pattern, for example one from Creational patterns, and one from Structural.
If i need some help in code architecture i use this:
https://refactoring.guru/

I think, using this example you can remove properties AccountName and Task, because of request models in methods.

Body:
I have an existing C# console application that takes arguments and based on the arguments
creates an instance of markets (UK, US, MX..) using dependency injection.

Each market class does a 'string GetData()', 'string  ProcessData()' and 'bool ExportData()'.

The application was initially created for one eCommerce vendor's markets. Now I am told to modify it for a different vendor that does a different process. The high-level flow remains the same.

'GetData' to fetch records from DB,

'ProcessData' for any transformation or the likes

'ExportData'.

The difference is Getdata() pulls records from DB and maps to an object. I am planning to use Petapoco. 'ProcessData' might return a similar class. 'Exportdata' currently does an API call but for the new vendor, I have to write to a file.

I was reading up on patterns I am totally confused. At first, I thought I needed abstract factory pattern and now I think the factory method is what I should be using but I am not sure if I am doing it right. Need some guidance/review here. A sample cs file I created from my understanding of factory pattern. This code is based on the headfirst code samples.

using System;
using System.Collections.Generic;
using StatusExport.Models;

namespace factorymethod
{
    class Program
    {
        static void Main(string[] args)
        {
            ClientFactory factory = null;
            Console.WriteLine("Enter client code:");
            string clientCode= Console.ReadLine();
            switch (clientCode.ToLower())
            {
                case "costco":
                    factory = new CostcoFactory("accountname", "taskname");
                    break;
                    //NEw vendor might be added
                    //case "walmart"
                    //factory = new WalmartFactory("taskname", "type");
                    //break
                default:
                    break;
            }

            bool status = factory.ProcessData();
            Console.ReadKey();
        }
    }

    abstract class Client
    {
        public abstract string AccountName { get; }
        public abstract string Task { get; set; }
        //More properties might be added. Some may not even be used by some of the new vendors. For example, Costco Might need accountname and task. Tomorrow if walmart comes, they might not need these two or may need task and a new property 'type'
        public abstract List<T> GetData<T>();
        public abstract List<T> ProcessData<T>();
        public abstract bool ExportData();
    }

    class CostcoClient : Client
    {
        public override string AccountName { get; }
        public override string Task { get; set; }

        public CostcoClient(string accountName, string task)
        {
            AccountName = accountName;
            Task = task;
        }

        public override List<DBRecord> GetData<DBRecord>() //DBRecord class is specific to Costco.
        {
            List<DBRecord> dbresult = new List<DBRecord>();
            //dbresult = db return data mapped to an object DBRecord using petapoco. Another vendor might have a different class to which DB records are mapped. So the return type can be generic
            return asn;
        }

        public override List<T> ProcessData<T>()
        {
            throw new NotImplementedException(); //Any data transformation or business logic. Return type might be DBRecord or a new class altogether
        }

        public override bool ExportData()
        {
            throw new NotImplementedException();//Call API or write data to file and if success send true else false
        }
    }

    abstract class ClientFactory
    {
        public abstract bool ProcessData();
    }

    class CostcoFactory : ClientFactory
    {
        public string AccountName { get; }
        public string Task { get; set; }
        public CostcoFactory(string accountname, string task)
        {
            AccountName = accountname;
            Task = task;
        }

        public override bool ProcessData()
        {
            CostcoClient gc = new CostcoClient(AccountName, Task);
            var result = gc.GetData<DBRecord>();
            return true;
        }
    }
}

Do you think this is the right design approach?

I also want to keep the console project independent of vendor project. So maybe 'StatusExport.Program' for the console application. DLL projects StatusExport.Common to hold the interface and abstract classes' and 'StatusExport.Client(ex:StatusExport.Costco)' for each vendor stuff.

Body:
You can create BaseClient class that will contains a basic group of properties, and if you need to add something new - just inherit it. You did right, but i think it's better to change public modifier to protected in your properties AccountName and Task, to give access to them only from child classes.
Actually, you can create a BaseClientModels (request/response) for each method if you are not sure that returning type List will be always actual.
Example:

public abstract class BaseClient
{
    #region Properties : Protected

    protected abstract string AccountName { get; }

    protected abstract string Task { get; set; }

    #endregion

    #region Methods : Public

    public abstract BaseGetDataResponseModel GetData(BaseGetDataRequestModel model);

    public abstract BaseProcessDataResponseModel ProcessData(BaseProcessDataRequestModel model);

    public abstract BaseExportDataResponseModel ExportData(BaseExportDataRequestModel model);

    #endregion
}

public class BaseGetDataResponseModel { }

public class BaseGetDataRequestModel { }

public class BaseProcessDataResponseModel { }

public class BaseProcessDataRequestModel { }

public class BaseExportDataResponseModel { }

public class BaseExportDataRequestModel { }

Then let's look on your class CostcoClient and how it can looks like:

public class CostcoClient : BaseClient
{
    #region Properties : Protected

    protected override string AccountName { get; }

    protected override string Task { get; set; }

    protected virtual IDataReader<BaseGetDataRequestModel, BaseGetDataResponseModel> DataReader { get; }

    protected virtual IDataProcessor<CostcoClientProcessDataRequestModel, CostcoClientProcessDataResponseModel> DataProcessor { get; }

    protected virtual IExportDataHandler<CostcoClientExportDataRequestModel, CostcoClientExportDataResponseModel> ExportDataHandler { get; }

    #endregion

    #region Constructors

    public CostcoClient(string accountName, string task)
    {
//set DataReader, DataProcessor, ExportDataHandler
        AccountName = accountName;
        Task = task;
    }

    #endregion

    #region Methods : Public

    public override BaseGetDataResponseModel GetData(BaseGetDataRequestModel model)
    {
        if (model is CostcoClientGetDataRequestModel clientGetDataRequestModel)
        {
            return DataReader.ReadData(clientGetDataRequestModel);
        }
        return null; //wrong type has passed
    }

    public override BaseProcessDataResponseModel ProcessData(BaseProcessDataRequestModel model)
    {
        if (model is CostcoClientProcessDataRequestModel clientProcessDataRequestModel)
        {
            return DataProcessor.ProcessData(clientProcessDataRequestModel);
        }
        return null;
    }

    public override BaseExportDataResponseModel ExportData(BaseExportDataRequestModel model)
    {
        if (model is CostcoClientExportDataRequestModel clientExportDataRequestModel)
        {
            return ExportDataHandler.Handle(clientExportDataRequestModel);
        }
        return null;
    }

    #endregion
}

public class CostcoClientGetDataRequestModel : BaseGetDataRequestModel { }

public class CostcoClientGetDataResponseModel : BaseGetDataResponseModel { }

public class CostcoClientProcessDataRequestModel : BaseProcessDataRequestModel { }

public class CostcoClientProcessDataResponseModel : BaseProcessDataResponseModel { }

public class CostcoClientExportDataRequestModel : BaseExportDataRequestModel { }

public class CostcoClientExportDataResponseModel : BaseExportDataResponseModel { }

public interface IDataReader<TIn, TOut>
{
    public TOut ReadData(TIn model);
}

public interface IDataProcessor<TIn, TOut>
{
    public TOut ProcessData(TIn model);
}

public interface IExportDataHandler<TIn, TOut>
{
    public TOut Handle(TIn model);
}

public class CostcoClientDataReader : IDataReader<CostcoClientGetDataRequestModel, CostcoClientGetDataResponseModel>
{
    public CostcoClientGetDataResponseModel ReadData(CostcoClientGetDataRequestModel model)
    {
        throw new NotImplementedException();
    }
}

    //and so on

You have to implement IDataReader, IDataProcessor, IExportDataHandler, make your logic and call it from GetData, ProcessData, ExportData methods, as an example, and get instances via dependency injection.

Then, we can change your factory to this:

public interface IClientFactory
{
    BaseClient GetClientService(ClientServicesEnum value);
}

public class BaseClientFactory : IClientFactory
{
    #region Propertied : Protected

    protected virtual IEnumerable<BaseClient> Services { get; }

    protected string AccountName { get; }

    protected string Task { get; set; }

    #endregion

    #region Constructors

    public BaseClientFactory(IEnumerable<BaseClient> services, string accountname, string task)
    {
        Services = services;
        AccountName = accountname;
        Task = task;
    }

    #endregion

    public BaseClient GetClientService(ClientServicesEnum value)
        => Services.First(x => x.GetType().Equals(GetClientServiceByCode()[value]));

    private Dictionary<ClientServicesEnum, Type> GetClientServiceByCode()
        => new Dictionary<ClientServicesEnum, Type>()
        {
            { ClientServicesEnum.CostcoClient, typeof(CostcoClient) }
        };

}

public enum ClientServicesEnum
{
    CostcoClient = 1,
    Another2 = 2,
    Another3 = 3
}

Where

protected virtual IEnumerable<BaseClient> Services { get; }

you can get via DI too, and then get correct ServiceHandler by enum.

And your main function to call all this:

        switch (clientCode)
        {
            case 1:
                baseClient = ClientFactory.GetClientService(ClientServicesEnum.CostcoClient);
                break;
            case 2:
                baseClient = ClientFactory.GetClientService(ClientServicesEnum.Another2);
                break;
            default:
                break;
        }

        bool status = baseClient.ProcessData(null); //your model

The main thing is - you can use more than one pattern, for example one from Creational patterns, and one from Structural.
If i need some help in code architecture i use this:
https://refactoring.guru/

I think, using this example you can remove properties AccountName and Task, because of request models in methods.


问:
How to update an internal table with another internal table?
I have this table and you'll notice that column VKBUR is empty:

What is the best way to populate this column with entries from another table using column VKGRP as key?

In summary, I would like to populate column VKBUR using data from L_T_ZCUSTSL04 as source. Their key is VKGRP from both tables:

Using this lookup table, I want to pass values from VKBUR into the above table.

Thank you so much for your assistance and have a good weekend.

答:
If you are working with 7.4 or newer, consider the following example based on CORRESPONDING constructor operator.

```<code>TYPES: BEGIN OF gs_report,
         equnr TYPE equnr,
         eqtyp TYPE eqtyp,
        anlage TYPE anlage,
         sernr TYPE serge,
       END OF gs_report.

DATA: gt_msrpoint TYPE SORTED TABLE OF gs_report WITH NON-UNIQUE key anlage.

SELECT equi~equnr, equi~eqtyp, eanl~anlage, sernr UP TO 50 rows
  INTO TABLE @gt_msrpoint
  FROM eanl
  JOIN eastl ON eastl~anlage     = eanl~anlage
  JOIN egerh ON egerh~logiknr    = eastl~logiknr
  LEFT JOIN equi ON  egerh~equnr = equi~equnr.

SELECT equi~matnr, equi~objnr, eanl~anlage, serge AS sernr UP TO 50 rows
  INTO TABLE @DATA(gt_msrpoint1)
  FROM eanl
  JOIN eastl ON  eastl~anlage    = eanl~anlage
  JOIN egerh ON  egerh~logiknr   = eastl~logiknr
  LEFT JOIN equi ON  egerh~equnr = equi~equnr.

gt_msrpoint1 = CORRESPONDING #( gt_msrpoint1 FROM gt_msrpoint USING anlage = anlage  ).
</code>```

Tested and it works.

Body:
If you are working with 7.4 or newer, consider the following example based on CORRESPONDING constructor operator.

TYPES: BEGIN OF gs_report,
         equnr TYPE equnr,
         eqtyp TYPE eqtyp,
        anlage TYPE anlage,
         sernr TYPE serge,
       END OF gs_report.

DATA: gt_msrpoint TYPE SORTED TABLE OF gs_report WITH NON-UNIQUE key anlage.

SELECT equi~equnr, equi~eqtyp, eanl~anlage, sernr UP TO 50 rows
  INTO TABLE @gt_msrpoint
  FROM eanl
  JOIN eastl ON eastl~anlage     = eanl~anlage
  JOIN egerh ON egerh~logiknr    = eastl~logiknr
  LEFT JOIN equi ON  egerh~equnr = equi~equnr.

SELECT equi~matnr, equi~objnr, eanl~anlage, serge AS sernr UP TO 50 rows
  INTO TABLE @DATA(gt_msrpoint1)
  FROM eanl
  JOIN eastl ON  eastl~anlage    = eanl~anlage
  JOIN egerh ON  egerh~logiknr   = eastl~logiknr
  LEFT JOIN equi ON  egerh~equnr = equi~equnr.

gt_msrpoint1 = CORRESPONDING #( gt_msrpoint1 FROM gt_msrpoint USING anlage = anlage  ).

Tested and it works.


问:
Recv interfering with recvfrom inside same select statement in C
I'm trying to create a select server that can handle both TCP and UDP conenctions, but when I try to recieve a UDP message, the prescence of my recv stops the code from reaching the recvfrom.  I can still reciveve the UDP message if I send it twice (not sure why).  How might I change this to correctly recieve from tcpfd on recv, and udpfd on recvfrom (those are the only two read fd's that will ever be in the read master set)?

The UDP message is being sent from an identical server on the same computer (and is sent correctly), and both sockets I'm using have been correctly set up.  The recvfrom works correctly if I remove the recv if statement.
Code is based on https://www.gnu.org/software/libc/manual/html_node/Server-Example.html#Server-Example

```<code>while (1)
{
    //masterset is contains 'tcpfd' and 'udpfd' for the tcp and udp socket I want to listen to
    readset = master;

    if (select(FD_SETSIZE, &readset, NULL, NULL, NULL) >= 0)
    {
        for (int i = 0; i <= FD_SETSIZE; i++)
        {
            len = sizeof servaddr;

            if (FD_ISSET(i, &readset))
            {

                if (i == tcpfd)
                {
                    int new;
                    new = accept(tcpfd, (struct sockaddr *)&servaddr, &len);
                    if (new < 0)
                    {
                        perror("accept");
                        exit(EXIT_FAILURE);
                    }
                    else
                    {
                        FD_SET(new, &masterset);
                    }
                }

                else if ((i != udpfd) && ((nbytes = recv(i, buffer, sizeof(buffer), 0)) > 0))
                {

                }

                else if ((i == udpfd) && (nbytes = recvfrom(udpfd, buffer, sizeof(buffer), 0,
                (struct sockaddr *)&servaddr, &len)) > 0)
                {

                }
            }
        }
    }
</code>```

答:
There are multiple problems with your code, but the one most likely causing the problem is that select modifies the sets you pass to it.

That means if readset have two descriptors sets in it but only one is readable, then the second will be removed from the set.

You need to reset the sets you pass to select before the next call in the loop. I assume that's what masterset is supposed to be used for, but you forgot to actually use it.

As for the other problems, the most serious is the loop condition i <= FD_SETSIZE. Descriptor sets are really arrays, and your loop will lead to an off-by-one error and out-of-bounds indexing into the array. This of course leads to undefined behavior.

Body:
I'm trying to create a select server that can handle both TCP and UDP conenctions, but when I try to recieve a UDP message, the prescence of my recv stops the code from reaching the recvfrom.  I can still reciveve the UDP message if I send it twice (not sure why).  How might I change this to correctly recieve from tcpfd on recv, and udpfd on recvfrom (those are the only two read fd's that will ever be in the read master set)?

The UDP message is being sent from an identical server on the same computer (and is sent correctly), and both sockets I'm using have been correctly set up.  The recvfrom works correctly if I remove the recv if statement.
Code is based on https://www.gnu.org/software/libc/manual/html_node/Server-Example.html#Server-Example

while (1)
{
    //masterset is contains 'tcpfd' and 'udpfd' for the tcp and udp socket I want to listen to
    readset = master;

    if (select(FD_SETSIZE, &readset, NULL, NULL, NULL) >= 0)
    {
        for (int i = 0; i <= FD_SETSIZE; i++)
        {
            len = sizeof servaddr;

            if (FD_ISSET(i, &readset))
            {

                if (i == tcpfd)
                {
                    int new;
                    new = accept(tcpfd, (struct sockaddr *)&servaddr, &len);
                    if (new < 0)
                    {
                        perror("accept");
                        exit(EXIT_FAILURE);
                    }
                    else
                    {
                        FD_SET(new, &masterset);
                    }
                }

                else if ((i != udpfd) && ((nbytes = recv(i, buffer, sizeof(buffer), 0)) > 0))
                {

                }

                else if ((i == udpfd) && (nbytes = recvfrom(udpfd, buffer, sizeof(buffer), 0,
                (struct sockaddr *)&servaddr, &len)) > 0)
                {

                }
            }
        }
    }


问:
NotConnectedException error in WebDriver tests running under Jenkins on Linux
I have a WebDriver test using the FirefoxDriver that I am attempting to run as a Jenkins job.

It works fine in Windows, it also works from the command line in Linux, where my Jenkins server lives.

Unfortunately, I got the following error during executing as a Jenkins job:

```<code>org.openqa.selenium.firefox.NotConnectedException: Unable to connect to host 127.0.0.1 on port 7055 after 45000 ms
</code>```

The Jenkins job consists of 2 steps: a shell step that executes:

```<code>Xvfb :1 -screen 0 1024x768x24 &
export DISPLAY=:1
</code>```

And then a maven package to run the test class.

Why can't I get the Jenkins job to execute Firefox?

答:
When you run the job from jenkins, it runs the same test as "Jenkins" user. You need to add one more line in etc/hosts file for jenkins user like</p>

```<code>your.ip.address.value jenkins
</code>```

Body:
I have a WebDriver test using the FirefoxDriver that I am attempting to run as a Jenkins job.

It works fine in Windows, it also works from the command line in Linux, where my Jenkins server lives.

Unfortunately, I got the following error during executing as a Jenkins job:

org.openqa.selenium.firefox.NotConnectedException: Unable to connect to host 127.0.0.1 on port 7055 after 45000 ms

The Jenkins job consists of 2 steps: a shell step that executes:

Xvfb :1 -screen 0 1024x768x24 &
export DISPLAY=:1

And then a maven package to run the test class.

Why can't I get the Jenkins job to execute Firefox?

Body:
When you run the job from jenkins, it runs the same test as "Jenkins" user. You need to add one more line in etc/hosts file for jenkins user like

your.ip.address.value jenkins


问:
Javascript | Can´t show session variable with alert
I am new in Javascript world, for any reason, alert can´t show 7. It is a simple example of saving in session variable and retrieving it. Why?

Thanks!

Javascript:

var corrects = 7;
sessionStorage.setItem('corrects', corrects);
corrects = sessionStorage.setItem('corrects');
alert("corrects:" + corrects);```

答:
Guess what you want to do and write the answer

```<code>var corrects = 7;
sessionStorage.setItem('corrects', corrects);
corrects = sessionStorage.getItem('corrects');
alert("corrects:" + corrects);
</code>```

Explanation

```<code>window.sessionStorage.getItem('corrects', corrects);
</code>```

the getItem method cannot take two arguments, and the getItem method is used for Get, not for save.
You save data with setItem method.

Body:
Guess what you want to do and write the answer

var corrects = 7;
sessionStorage.setItem('corrects', corrects);
corrects = sessionStorage.getItem('corrects');
alert("corrects:" + corrects);

Explanation

window.sessionStorage.getItem('corrects', corrects);

the getItem method cannot take two arguments, and the getItem method is used for Get, not for save.
You save data with setItem method.


问:
Angular Material - table mat-table not rendering data from rest api
I have been trying to implement mat-table in angular 8.
I don't understand what I'm doing wrong, the data which is being provided by my REST endpoint is clearly visible on the console output.

my admin.component.html file

```<code>    <table mat-table [dataSource]="dataSource">
        <!-- <ng-container *ngFor="let value of values;let i=index;">
            <tr *ngFor ="let row of {{value.rows}};let i = index;">
                <th mat-header-cell *matHeaderCellDef>{{row.header}}</th>
                <td mat-cell>{{}}</td>
            </tr>
        </ng-container> -->

        <ng-container matColumnDef="position">
                <th mat-header-cell *matHeaderCellDef> No.</th>
                <td mat-cell *matCellDef="let data"> {{data.position}} </td>
              </ng-container>

        <ng-container matColumnDef="USERNAME">
                <th mat-header-cell *matHeaderCellDef> USERNAME</th>
                <td mat-cell *matCellDef="let data"> {{data.username}} </td>
              </ng-container>

              <!-- Name Column -->
              <ng-container matColumnDef="BU">
                <th mat-header-cell *matHeaderCellDef> BU</th>
                <td mat-cell *matCellDef="let data"> {{data.BU}} </td>
              </ng-container>

              <!-- Weight Column -->
              <ng-container matColumnDef="DURATION">
                <th mat-header-cell *matHeaderCellDef> DURATION </th>
                <td mat-cell *matCellDef="let data"> {{data.duration}} </td>
              </ng-container>

              <!-- Symbol Column -->
              <ng-container matColumnDef="PURPOSE">
                <th mat-header-cell *matHeaderCellDef> PURPOSE</th>
                <td mat-cell *matCellDef="let data"> {{data.remarks}} </td>
              </ng-container>
              <ng-container matColumnDef="apr">
                    <th mat-header-cell *matHeaderCellDef>
                         <mat-checkbox (change)="$event ? masterToggle() : null"
                                        [checked]="selection.hasValue() && isAllSelected()"
                                        [indeterminate]="selection.hasValue() && !isAllSelected()"
                                        [aria-label]="checkboxLabel()">
                                APPROVE</mat-checkbox></th>
                    <td mat-cell *matCellDef="let row" >
                            <mat-checkbox (click)="$event.stopPropagation()"
                                          (change)="$event ? selection.toggle(row) : null"
                                            [checked]="selection.isSelected(row)"
                                            [aria-label]="checkboxLabel(row)">Approve</mat-checkbox>
                    </td>
                  </ng-container>

                  <ng-container matColumnDef="rej">
                        <th mat-header-cell *matHeaderCellDef> REJECT</th>
                        <td mat-cell *matCellDef="let row" >
                                <mat-checkbox >Reject</mat-checkbox>
                        </td>
                      </ng-container>

              <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
              <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
              <!-- <tr mat-footer-row *matFooterRowDef><button mat-button> Submit</button></tr> -->
            </table>
            <button mat-button color="primary" (click)="OnApprovalSubmit()">Submit</button>

</code>```

my ts file

```<code>export interface UserData{
  position:number;
  username:any;
  BU:any;
  duration:any;
  remarks:string;

}

@Component({
  selector: 'app-admin',
  templateUrl: 'admin.component.html',
  styleUrls: ['./app.component.css']
})

export class AdminComponent implements OnInit{
  displayedColumns: string[] = ['position','USERNAME', 'BU', 'DURATION', 'PURPOSE','apr','rej'];
  USER_DATA:any;

  // approve:any;
  // reject:any;

  constructor(public testService : TestService){}
  ngOnInit(){
    this.testService.getUserAccessDetails().subscribe(data =>{
      console.log(data);
      this.USER_DATA=data.USER_DATA;
      console.log(this.USER_DATA);

    })

  }

  dataSource = new MatTableDataSource<UserData>(this.USER_DATA);
  // console.log(this.USER_DATA);
  selection = new SelectionModel<UserData>(true, []);

  isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSource.data.length;
    return numSelected === numRows;
  }

  /** Selects all rows if they are not all selected; otherwise clear selection. */
  masterToggle() {
    console.log(this.USER_DATA);
    this.isAllSelected() ?
        this.selection.clear() :
        this.dataSource.data.forEach(row => this.selection.select(row));
  }

  /** The label for the checkbox on the passed row */
  checkboxLabel(row?: UserData): string {
    if (!row) {
      return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
    }
    return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
  }

}

</code>```

when the console data it is coming in this format

```<code>USER_DATA: Array(1)
0: {position: "01", username: "NAme", BU: "Team", Duration: 3, remarks: "NA"}
</code>```

but still no rows are getting rendered and there is no error also.
Any help on this would be appreciated.

答:
You can even try this if you don't want to instantiate MatTableDataSource inside subscrbie function.

export class AdminComponent implements OnInit{

  displayedColumns: string[] = ['position', 'USERNAME', 'BU', 'DURATION','PURPOSE','apr','rej'];
  dataSource = new MatTableDataSource<UserData>();

  ngOnInit() {
    this.testService.getUserAccessDetails()
    .subscribe(data => {
         this.dataSource.data = data.USER_DATA;
    });
  }
}
```

Body:
I have been trying to implement mat-table in angular 8.
I don't understand what I'm doing wrong, the data which is being provided by my REST endpoint is clearly visible on the console output.

my admin.component.html file

        <ng-container matColumnDef="position">
                 No.
                 {{data.position}}
              </ng-container>

        <ng-container matColumnDef="USERNAME">
                 USERNAME
                 {{data.username}}
              </ng-container>

              <ng-container matColumnDef="BU">
                 BU
                 {{data.BU}}
              </ng-container>

              <ng-container matColumnDef="DURATION">
                 DURATION
                 {{data.duration}}
              </ng-container>

              <ng-container matColumnDef="PURPOSE">
                 PURPOSE
                 {{data.remarks}}
              </ng-container>
              <ng-container matColumnDef="apr">

                         <mat-checkbox (change)="$event ? masterToggle() : null"
                                        [checked]="selection.hasValue() && isAllSelected()"
                                        [indeterminate]="selection.hasValue() && !isAllSelected()"
                                        [aria-label]="checkboxLabel()">
                                APPROVE</mat-checkbox>

                            <mat-checkbox (click)="$event.stopPropagation()"
                                          (change)="$event ? selection.toggle(row) : null"
                                            [checked]="selection.isSelected(row)"
                                            [aria-label]="checkboxLabel(row)">Approve</mat-checkbox>

                  </ng-container>

                  <ng-container matColumnDef="rej">
                         REJECT

                                <mat-checkbox >Reject</mat-checkbox>

                      </ng-container>

            <button mat-button color="primary" (click)="OnApprovalSubmit()">Submit</button>

my ts file

export interface UserData{
  position:number;
  username:any;
  BU:any;
  duration:any;
  remarks:string;

}

@Component({
  selector: 'app-admin',
  templateUrl: 'admin.component.html',
  styleUrls: ['./app.component.css']
})

export class AdminComponent implements OnInit{
  displayedColumns: string[] = ['position','USERNAME', 'BU', 'DURATION', 'PURPOSE','apr','rej'];
  USER_DATA:any;

  // approve:any;
  // reject:any;

  constructor(public testService : TestService){}
  ngOnInit(){
    this.testService.getUserAccessDetails().subscribe(data =>{
      console.log(data);
      this.USER_DATA=data.USER_DATA;
      console.log(this.USER_DATA);

    })

  }

  dataSource = new MatTableDataSource<UserData>(this.USER_DATA);
  // console.log(this.USER_DATA);
  selection = new SelectionModel<UserData>(true, []);

  isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSource.data.length;
    return numSelected === numRows;
  }

  /** Selects all rows if they are not all selected; otherwise clear selection. */
  masterToggle() {
    console.log(this.USER_DATA);
    this.isAllSelected() ?
        this.selection.clear() :
        this.dataSource.data.forEach(row => this.selection.select(row));
  }

  /** The label for the checkbox on the passed row */
  checkboxLabel(row?: UserData): string {
    if (!row) {
      return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
    }
    return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
  }

}

when the console data it is coming in this format

USER_DATA: Array(1)
0: {position: "01", username: "NAme", BU: "Team", Duration: 3, remarks: "NA"}

but still no rows are getting rendered and there is no error also.
Any help on this would be appreciated.