javascript - react samma nycklar trycktes in i en tabellrad beroende på användar-ID


Så jag hämtar mina data från ett API som returnerar detta:

appointments: [0: {customerId: 1, customerName: john, serviceName: serviceName1, start: {dateTime:"15:00"}, end: {dateTime:"16:00"}},
1: {customerId: 2, customerName: doe, serviceName: serviceName2, start: {dateTime:"14:00"}, end: {dateTime:"15:00"}},
2: {customerId: 2, customerName: doe,serviceName: serviceName3 , start: {dateTime:"12:00"}, end: {dateTime:"13:00"}}]

mitt kodstycke

render() {
return (
  <div>
    <Table>
      <thead>
        <tr>
          <th scope="col">room</th>
          <th scope="col">customer name</th>
          <th scope="col">serviceName1</th>
          <th scope="col">serviceName 2</th>
          <th scope="col">serviceName 3</th>
          <th scope="col">other</th>
        </tr>
      </thead>
      <tbody>
        {this.state.appointments.map((appointments: any, index) => {
          return (
            <tr key={appointments.customerId}>
              <td>{index + 1}</td>
              <td>{appointments.customerName}</td>
              {}
              <td>{`${formatDateTime(
                appointments.start?.dateTime
              )} - ${formatDateTime(appointments.end?.dateTime)}`}</td>
            </tr>
          );
        })}
      </tbody>
    </Table>
  </div>

Min fråga är hur jag kan trycka beroende på kund-ID hans båda tjänster (serviceName 2 och serviceName 3) i samma rad och varje rad fyller i det lämpliga rubriken tiden för varje tjänst?

Svar #1

Du kan förbehandla dina data för att minska dubbletterna till enskilda poster att kartlägga i ditt användargränssnitt. Slå ihop tjänsterna och tiderna i en nästlad array för att kartlägga i ytterligare tjänstekolumner.

Object.values(
  data.reduce(
    (dataObj, current) => ({
      ...dataObj,
      [current.customerId]: {
        ...dataObj[current.customerId],
        customerId: current.customerId,
        customerName: current.customerName,
        services: (dataObj[current.customerId]?.services || []).concat({
          serviceName: current.serviceName,
          start: current.start,
          end: current.end
        })
      }
    }),
    {}
  )
);

const data = [
  {
    customerId: 1,
    customerName: "john",
    serviceName: "serviceName1",
    start: { dateTime: "15:00" },
    end: { dateTime: "16:00" }
  },
  {
    customerId: 2,
    customerName: "doe",
    serviceName: "serviceName2",
    start: { dateTime: "14:00" },
    end: { dateTime: "15:00" }
  },
  {
    customerId: 2,
    customerName: "doe",
    serviceName: "serviceName3",
    start: { dateTime: "12:00" },
    end: { dateTime: "13:00" }
  }
];

const processedData = Object.values(
  data.reduce(
    (dataObj, current) => ({
      ...dataObj,
      [current.customerId]: {
        ...dataObj[current.customerId],
        customerId: current.customerId,
        customerName: current.customerName,
        services: (dataObj[current.customerId]?.services || []).concat({
          serviceName: current.serviceName,
          start: current.start,
          end: current.end
        })
      }
    }),
    {}
  )
);

console.log(processedData);

Kartlägg de bearbetade mötesuppgifterna.

render() {
  return (
    <div>
      <Table>
        <thead>
          <tr>
            <th scope="col">room</th>
            <th scope="col">customer name</th>
            <th scope="col">serviceName1</th>
            <th scope="col">serviceName 2</th>
            <th scope="col">serviceName 3</th>
            <th scope="col">other</th>
          </tr>
        </thead>
        <tbody>
          {processedAppointments.map((appointments: any, index) => {
            return (
              <tr key={appointments.customerId}>
                <td>{index + 1}</td>
                <td>{appointments.customerName}</td>
                {
                  appointments.services.map((service) => (
                    <td key={service.serviceName}>
                      {`${formatDateTime(service.start?.dateTime)} - ${formatDateTime(service.end?.dateTime)}`}
                    </td>
                  ))
                }
              </tr>
            );
          })}
        </tbody>
      </Table>
    </div>

Eftersom det verkar som om du bara har 3 servicekolumner, om dina data råkar innehålla fler än så bör du skiva ut det du behöver från de bearbetade uppgifterna. D.v.s. något som appointments.services.slice(-3).map(... för att ta upp till de sista 3.

Svar #2

Prova detta, jag har lagt till index som nyckel eftersom index är unikt i ditt fall

render() {
return (
  <div>
    <Table>
      <thead>
        <tr key="heading">
          <th scope="col">room</th>
          <th scope="col">customer name</th>
          <th scope="col">serviceName1</th>
          <th scope="col">serviceName 2</th>
          <th scope="col">serviceName 3</th>
          <th scope="col">other</th>
        </tr>
      </thead>
      <tbody>
        {this.state.appointments.map((appointments: any, index) => {
          return (
            <tr key={index}>
              <td>{index + 1}</td>
              <td>{appointments.customerName}</td>
              <td>{`${formatDateTime(
                appointments.start?.dateTime
              )} - ${formatDateTime(appointments.end?.dateTime)}`}</td>
            </tr>
          );
        })}
      </tbody>
    </Table>
  </div>