Home > Blockchain >  startsWith only working for first condition
startsWith only working for first condition

Time:06-24

Im having a bit of an issue and im not sure where I am going wrong. I have a Map which is bringin in prices, based on the ID of the product I need to add a discount or skip it.

let discountPrice = !prod.ProductID.startsWith('BGM', 'S11', 'BGP') && prod.CurrentPrice.toString().endsWith('97') ? parseFloat(prod.CurrentPrice) * 0.05 : !prod.ProductID.startsWith('BGM', 'S11', 'BGP') ? parseFloat(prod.CurrentPrice) * 0.15 : 0
let dp =  usdNumber.format( discountPrice )
let finalPrice = parseFloat(prod.CurrentPrice) - parseFloat(discountPrice)
let totalWithQ = finalPrice * prod.Quantity
let fp =  usdNumber.format( totalWithQ )

This works great for BGM it will skip the discount but for S11 and BGP it will still apply the discount where if the product ID has BGM, S11 or BGP i want it to skip.

results

Am I using startsWith wrong? Can it not pass multiple things through it and have it loop through per argument?

    {User?.Cart && User?.Cart.length > 0 && (
            <>
              <Table>
                <Thead>
                  <Tr className="text-left border-b-2 border-blue">
                    <Th className="py-5">Product</Th>
                    <Th className="py-5">Price</Th>
                    <Th className="py-5">Overstock Discount Per Item</Th>
                    <Th className="py-5">Quantity</Th>
                    <Th className="py-5">Total Price</Th>
                    <Th className="py-5">Controls</Th>
                  </Tr>
                </Thead>
                <Tbody>
                  {User.Cart.map((prod, i) => {
                    let discountPrice = !prod.ProductID.startsWith('BGM', 'S11', 'BGP') && prod.CurrentPrice.toString().endsWith('97') ? parseFloat(prod.CurrentPrice) * 0.05 : !prod.ProductID.startsWith('BGM', 'S11', 'BGP') ? parseFloat(prod.CurrentPrice) * 0.15 : 0
                    let dp =  usdNumber.format( discountPrice )
                    let finalPrice = parseFloat(prod.CurrentPrice) - parseFloat(discountPrice)
                    let totalWithQ = finalPrice * prod.Quantity
                    let fp =  usdNumber.format( totalWithQ )
                    return (
                      <Tr
                        key={`key-cart-prod-${i}`}
                        className="border-b border-opacity-50 border-Blue"
                      >
                        <Td className="py-5">
                          <Link href={`/product/${prod.Slug}`}>
                            <a>
                              {`${prod.Description} (${prod.ProductID})`}
                            </a>
                          </Link>
                        </Td>
                        <Td className="py-5">{`$${prod.CurrentPrice}`}</Td>
                        <Td className="py-5">{`${dp}`}</Td>
                        <Td className="py-5">{`Qty: ${prod.Quantity}`}</Td>
                        <Td className="py-5">{`${fp}`}</Td>
                        <Td className="py-5" style={{width: '1%', whiteSpace: 'nowrap'}}>
                          <RemoveFromCart ProductID={prod.ProductID} />
                        </Td>
                      </Tr>
                    )
                  })}
                </Tbody>

CodePudding user response:

It is not possible to pass multiple options into startsWith() method.

The method has following syntax: string.startsWith(searchValue, start)

You can try:

  1. Checking startsWith for each string separately:
!(prod.ProductID.startsWith('BGM') || prod.ProductID.startsWith('S11') || prod.ProductID.startsWith('BGP'))
  1. Looping through array of options:
!['BGM', 'S11', 'BGP'].some(item => prod.ProductID.startsWith(item))
  1. Using regular expression:
!/^(BGM|S11|BGP)/.test(prod.ProductID)

CodePudding user response:

That's simply not how startsWith works. You can only supply it a single test string (and, optionally and rarely, a start position.)

Try replacing

! prod.ProductID .startsWith ('BGM', 'S11', 'BGP')

with

! (['BGM', 'S11', 'BGP'] .some (s => prod .ProductID .startsWith (s)))

or equivalently,

(['BGM', 'S11', 'BGP'] .every (s => ! prod .ProductID .startsWith (s)))

depending on which makes more sense to you, and doing the same for your CurrentPrice. That may capture what you need.

CodePudding user response:

String.prototype.startsWith, cannot be passed three separate strings to check.

If your pseudo code is:

If product ID does not begin with BGM, S11, or BGP,

then you could test it with a regular expression or else use three separate statements like so:

let discountPrice = (!prod.ProductID.startsWith('BGM') &&
    !prod.ProductID.startsWith('S11') &&
    !prod.ProductID.startsWith('BGP') &&
    prod.CurrentPrice.toString().endsWith('97'))
    ? parseFloat(prod.CurrentPrice) * 0.05
    : !prod.ProductID.startsWith('BGM', 'S11', 'BGP')
        ? parseFloat(prod.CurrentPrice) * 0.15
        : 0

Using a regex:

let discountPrice = (!/^(S11|BGP|BGM)/.test(prod.ProductID) && prod.CurrentPrice.toString().endsWith('97'))
    ? parseFloat(prod.CurrentPrice) * 0.05
    : !prod.ProductID.startsWith('BGM', 'S11', 'BGP')
        ? parseFloat(prod.CurrentPrice) * 0.15
        : 0
  • Related