-
-
Notifications
You must be signed in to change notification settings - Fork 130
Open
Description
API Platform version(s) affected: 3.2.11
Description
If an entity contains a manytoone relation, the pwa/component/nameOfEntity/list.tsx generate by Next gen contains error
I have two entity : Entreprise and Meet.
Class Entreprise
<?php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use App\Repository\EntrepriseRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use ApiPlatform\Metadata\Delete;
use Symfony\Component\Serializer\Annotation\Groups;
#[ORM\Entity(repositoryClass: EntrepriseRepository::class)]
#[ApiResource(
normalizationContext: ['groups' => ['entreprise:read']],
denormalizationContext: ['groups' => ['entreprise:write']],
)]
class Entreprise
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['entreprise:read'])]
private ?int $id = null;
#[ORM\Column(length: 255)]
#[Groups(['entreprise:read', 'entreprise:write', 'user:read'])]
private ?string $name = null;
#[ORM\Column(length: 255, nullable: true)]
#[Groups(['entreprise:read', 'entreprise:write', 'user:read'])]
private ?string $address_street = null;
#[ORM\Column(length: 255, nullable: true)]
#[Groups(['entreprise:read', 'entreprise:write', 'user:read'])]
private ?string $address_city = null;
#[ORM\Column(length: 255, nullable: true)]
#[Groups(['entreprise:read', 'entreprise:write', 'user:read'])]
private ?string $address_cp = null;
#[ORM\Column(options: ['default' => 0])]
#[Groups(['entreprise:read', 'entreprise:write', 'user:read'])]
private ?int $type = null;
#[ORM\OneToMany(mappedBy: 'entreprise_id', targetEntity: Meet::class, orphanRemoval: true)]
#[Groups(['entreprise:read', 'user:read'])]
private Collection $meets;
#[ORM\OneToMany(mappedBy: 'entreprise_id', targetEntity: Customer::class, orphanRemoval: true)]
#[Groups(['entreprise:read', 'user:read'])]
private Collection $customers;
#[ORM\OneToMany(mappedBy: 'entreprise_id', targetEntity: Employee::class, orphanRemoval: true)]
#[Groups(['entreprise:read', 'user:read'])]
private Collection $employees;
#[ORM\OneToMany(mappedBy: 'entreprise_id', targetEntity: User::class)]
#[Groups(['entreprise:read'])]
private Collection $users;
Class Meet
<?php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use App\Repository\MeetRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put;
use ApiPlatform\Metadata\Delete;
use Symfony\Component\Serializer\Annotation\Groups;
#[ORM\Entity(repositoryClass: MeetRepository::class)]
#[ApiResource(
normalizationContext: ['groups' => ['meet:read']],
denormalizationContext: ['groups' => ['meet:write']],
)]
class Meet
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
#[Groups(['meet:read', 'entreprise:read'])]
private ?int $id = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
#[Groups(['meet:read', 'meet:write', 'entreprise:read'])]
private ?\DateTimeInterface $date_start = null;
#[ORM\Column]
#[Groups(['meet:read', 'meet:write', 'entreprise:read'])]
private ?int $duration = null;
#[ORM\ManyToOne(inversedBy: 'meets')]
#[ORM\JoinColumn(nullable: false)]
#[Groups(['meet:read', 'meet:write'])]
private ?Entreprise $entreprise_id = null;
#[ORM\OneToMany(mappedBy: 'meet_id', targetEntity: Notification::class, orphanRemoval: true)]
#[Groups(['meet:read', 'meet:write', 'entreprise:read'])]
private Collection $notifications;
#[ORM\ManyToMany(targetEntity: Employee::class, mappedBy: 'meets')]
#[Groups(['meet:read', 'meet:write', 'entreprise:read'])]
private Collection $employees;
#[ORM\ManyToMany(targetEntity: Customer::class, inversedBy: 'meets')]
#[Groups(['meet:read', 'meet:write', 'entreprise:read'])]
private Collection $customers;
public function __construct()
{
$this->notifications = new ArrayCollection();
$this->employees = new ArrayCollection();
$this->customers = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getDateStart(): ?\DateTimeInterface
{
return $this->date_start;
}
public function setDateStart(\DateTimeInterface $date_start): static
{
$this->date_start = $date_start;
return $this;
}
public function getDuration(): ?int
{
return $this->duration;
}
public function setDuration(int $duration): static
{
$this->duration = $duration;
return $this;
}
public function getEntrepriseId(): ?Entreprise
{
return $this->entreprise_id;
}
public function setEntrepriseId(?Entreprise $entreprise_id): static
{
$this->entreprise_id = $entreprise_id;
return $this;
}
/**
* @return Collection<int, Notification>
*/
public function getNotifications(): Collection
{
return $this->notifications;
}
public function addNotification(Notification $notification): static
{
if (!$this->notifications->contains($notification)) {
$this->notifications->add($notification);
$notification->setMeetId($this);
}
return $this;
}
public function removeNotification(Notification $notification): static
{
if ($this->notifications->removeElement($notification)) {
// set the owning side to null (unless already changed)
if ($notification->getMeetId() === $this) {
$notification->setMeetId(null);
}
}
return $this;
}
/**
* @return Collection<int, Employee>
*/
public function getEmployees(): Collection
{
return $this->employees;
}
public function addEmployee(Employee $employee): static
{
if (!$this->employees->contains($employee)) {
$this->employees->add($employee);
$employee->addMeet($this);
}
return $this;
}
public function removeEmployee(Employee $employee): static
{
if ($this->employees->removeElement($employee)) {
$employee->removeMeet($this);
}
return $this;
}
/**
* @return Collection<int, Customer>
*/
public function getCustomers(): Collection
{
return $this->customers;
}
public function addCustomer(Customer $customer): static
{
if (!$this->customers->contains($customer)) {
$this->customers->add($customer);
}
return $this;
}
public function removeCustomer(Customer $customer): static
{
$this->customers->removeElement($customer);
return $this;
}
}
pwa/components/meet/list.tsx
import { FunctionComponent } from "react";
import Link from "next/link";
import ReferenceLinks from "../common/ReferenceLinks";
import { getItemPath } from "../../utils/dataAccess";
import { Meet } from "../../types/Meet";
interface Props {
meets: Meet[];
}
export const List: FunctionComponent<Props> = ({ meets }) => (
<div className="p-4">
<div className="flex justify-between items-center">
<h1 className="text-3xl mb-2">Meet List</h1>
<Link
href="/meets/create"
className="bg-cyan-500 hover:bg-cyan-700 text-white text-sm font-bold py-2 px-4 rounded"
>
Create
</Link>
</div>
<table
cellPadding={10}
className="shadow-md table border-collapse min-w-full leading-normal table-auto text-left my-3"
>
<thead className="w-full text-xs uppercase font-light text-gray-700 bg-gray-200 py-2 px-4">
<tr>
<th>id</th>
<th>date_start</th>
<th>duration</th>
<th>entreprise_id</th>
<th>notifications</th>
<th>employees</th>
<th>customers</th>
<th colSpan={2} />
</tr>
</thead>
<tbody className="text-sm divide-y divide-gray-200">
{meets &&
meets.length !== 0 &&
meets.map(
(meet) =>
meet["@id"] && (
<tr className="py-2" key={meet["@id"]}>
<th scope="row">
<ReferenceLinks
items={{
href: getItemPath(meet["@id"], "/meets/[id]"),
name: meet["@id"],
}}
/>
</th>
<td>{meet["date_start"]?.toLocaleString()}</td>
<td>{meet["duration"]}</td>
<td>
{console.log()}
<ReferenceLinks
items={meet["entreprise_id"].map((ref: any) => ({
href: getItemPath(ref, "/entreprises/[id]"),
name: ref,
}))}/>
</td>
<td>
<ReferenceLinks
items={meet["notifications"].map((emb: any) => ({
href: getItemPath(emb["@id"], "/notifications/[id]"),
name: emb["@id"],
}))}
/>
</td>
<td>
<ReferenceLinks
items={meet["employees"].map((ref: any) => ({
href: getItemPath(ref, "/employees/[id]"),
name: ref,
}))}
/>
</td>
<td>
<ReferenceLinks
items={meet["customers"].map((ref: any) => ({
href: getItemPath(ref, "/customers/[id]"),
name: ref,
}))}
/>
</td>
<td className="w-8">
<Link
href={getItemPath(meet["@id"], "/meets/[id]")}
className="text-cyan-500"
>
Show
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
className="w-6 h-6"
>
<path d="M12 15a3 3 0 100-6 3 3 0 000 6z" />
<path
fillRule="evenodd"
d="M1.323 11.447C2.811 6.976 7.028 3.75 12.001 3.75c4.97 0 9.185 3.223 10.675 7.69.12.362.12.752 0 1.113-1.487 4.471-5.705 7.697-10.677 7.697-4.97 0-9.186-3.223-10.675-7.69a1.762 1.762 0 010-1.113zM17.25 12a5.25 5.25 0 11-10.5 0 5.25 5.25 0 0110.5 0z"
clipRule="evenodd"
/>
</svg>
</Link>
</td>
<td className="w-8">
<Link
href={getItemPath(meet["@id"], "/meets/[id]/edit")}
className="text-cyan-500"
>
Edit
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
className="w-6 h-6"
>
<path d="M21.731 2.269a2.625 2.625 0 00-3.712 0l-1.157 1.157 3.712 3.712 1.157-1.157a2.625 2.625 0 000-3.712zM19.513 8.199l-3.712-3.712-8.4 8.4a5.25 5.25 0 00-1.32 2.214l-.8 2.685a.75.75 0 00.933.933l2.685-.8a5.25 5.25 0 002.214-1.32l8.4-8.4z" />
<path d="M5.25 5.25a3 3 0 00-3 3v10.5a3 3 0 003 3h10.5a3 3 0 003-3V13.5a.75.75 0 00-1.5 0v5.25a1.5 1.5 0 01-1.5 1.5H5.25a1.5 1.5 0 01-1.5-1.5V8.25a1.5 1.5 0 011.5-1.5h5.25a.75.75 0 000-1.5H5.25z" />
</svg>
</Link>
</td>
</tr>
)
)}
</tbody>
</table>
</div>
);
Possible Solution
Error TypeError: meet.entreprise_id.map is not a function come from this code
<ReferenceLinks
items={meet["entreprise_id"].map((ref: any) => ({
href: getItemPath(ref, "/entreprises/[id]"),
name: ref,
}))}/>
meet["entreprise_id"] is not an array so it's impossible to map it
It's possible to solve with
items={[meet["entreprise_id"]].map((ref: any) => ({
href: getItemPath(ref, "/entreprises/[id]"),
name: ref,
}))}/>```
**Additional Context**
Metadata
Metadata
Assignees
Labels
No labels