0

Here is an example of my array (I simplified the array but there are about 100 elements and roughly 20 values for each element:

0:
odata.type: "SP.Data.ProductListItem"
Title: "This is Product 1"
Id: 1

1:
odata.type: "SP.Data.ProductListItem"
Title: "Dell Computer"
Id: 2

The url path is mysite.com/product/2 I created a product component which I want to check if and find product/:id exists in the array and matches the URL to then display that product's information.

So if you were to go to /product/1' you would see This is Product 1 title with it's coresponding info and if you go to product/2 you would see Dell Computer.

In my code I'm trying to save the state of the array because I'll be adding a form allowing certain users to update this page's information.

The pnp.sp.web.lists.getByTitle("Product") works, I'm having trouble getting the filter to work.

import * as React from 'react';
import { default as pnp, sp } from "sp-pnp-js";

export class Product extends React.Component<{ match: any }, {
  foundProduct: any,
}> {

  constructor(props) {
    super(props);
    this.state = {
      foundProduct: [],
    };
  }

  public componentDidMount() {
    const foundProduct = pnp.sp.web.lists.getByTitle("Product")
      .items
      .filter("Id eq '" + this.props.location.pathname, +"'")
      .top(1)
      .get()
      .then((items: any[]) => {
        this.setState({ foundProduct: [...foundProduct] });
      })
  }


  public render(): React.ReactElement<{}> {
    console.log(this);
    return (
      <div>
        <div className={styles.colHalf}>
          { this.state.foundProduct.ID }
        </div>
        <div className={styles.colHalf}>
          { this.state.foundProduct.Title}
        </div>
      </div>
    );
  }
}
Shlang
  • 2,495
  • 16
  • 24
hisusu32
  • 437
  • 7
  • 22
  • It seems that you wanted to pass `items` to your `setState` inside `then` – Shlang Apr 13 '20 at 17:54
  • @Shlang I'm having issues with the `.filter("ID eq '" + this.props.location.pathname, + "'")` it's not returning anything. – hisusu32 Apr 13 '20 at 18:17
  • Could you be more specific? What do you expect? How do you understand it returns nothing? As for now it seems that you expect it returns the value that you want to assing to `foundProduct` and then this value is used in `setState` inside` `then` but js does not work this way. – Shlang Apr 13 '20 at 18:23
  • @Shlang yes sorry about that so I was using `pnp.sp.web.lists.getByTitle("Products").items.get().then((items: any[]) => {` and it was returning an array of about 100 elements. Instead of returning 100 items I want it to just return the element with the ID that's the same as the URL. so as soon as I added the `.filter()` function it now returns nothing. – hisusu32 Apr 13 '20 at 18:34

1 Answers1

1

The condition inside the filter is unclear, perhaps you should do something like that:

(I'm not sure for the content of this.props.location.pathname )

public componentDidMount() {

        const foundProduct = pnp.sp.web.lists.getByTitle("Product").items.filter(item=>item.Id==this.props.location.pathname).top(1).get().then((items: any[]) => {

            this.setState({ foundProduct: [...foundProduct] });

        })          
    }

Hope it helps.

ESI
  • 1,657
  • 8
  • 18
  • Thank you! I ended up using `filter("Id eq '" + this.props.match.params.id + "'")` any thoughts on whether I should use `location.pathname` or `match.params.id` ? – hisusu32 Apr 14 '20 at 15:43
  • I'm not sure about your data structure, but if `this.props.match.params.id` contains the `Id ` that's probably what you need. Another thing, do you have duplicate keys you need to do `.top(1)`? – ESI Apr 16 '20 at 12:52
  • thank you, I got this working. I do not have duplicate keys. I added the `.top(1)` because I want it to search the array and as soon as it finds that key to stop filtering.. Since the array will contain 100+ elements I thought this would add to performance or is that not the issue? If the ID is the second item in the array I want it to stop filtering. and proceed – hisusu32 Apr 16 '20 at 15:07
  • I'm fairly certain that `filter()` calls a provided callback function once for each element in an array([see here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)),consider to use [find()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) :"The find method executes the callback function once for each index of the array until the callback returns a true value" [related question](https://stackoverflow.com/q/41322046/13029900) – ESI Apr 16 '20 at 16:36