# Link im Backend soll einen POST-Befehl ausführen

**URL:** <https://forum.shopware.com/t/link-im-backend-soll-einen-post-befehl-ausfuehren/105758>\
**Category:** Programmierung\
**Created:** [5. November 2024 um 18:31 UTC](https://forum.shopware.com/t/link-im-backend-soll-einen-post-befehl-ausfuehren/105758 "2024-11-05T18:31:23Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Karlex](https://avatars.discourse-cdn.com/v4/letter/k/a183cd/32.png) [@Karlex](https://forum.shopware.com/u/Karlex)\
**Post date:** [5. November 2024 um 18:31 UTC](https://forum.shopware.com/t/link-im-backend-soll-einen-post-befehl-ausfuehren/105758/1 "2024-11-05T18:31:23Z")

</div>

Ich versuche seit Stunden das Problem zu lösen aber schaffe es leider nicht. Ich bin noch recht unerfahren mit Plugins erstellen für Shopware.  
Ich möchte einen Link auf der Einstellungsseite für Produkte hinterlegen, wenn man auf diesen klickt (\<a href=„#“ @click.prevent=„generatePdf“\>PDF-Vorschau erstellen) soll in einem neuen Fenster die generierte PDF geöffnet werden.

```auto
import template from './sw-product-detail-specifications.html.twig';

const { Component } = Shopware;

Component.override('sw-product-detail-specifications', {
    template,

    methods: {
        generatePdf() {
            let htmlContent = document.getElementById('MyPlugin_html').value;
            const mediaField = document.querySelector('sw-media-field[name="MyPlugin_img"]');

            if (mediaField) {
                const mediaItem = mediaField.querySelector('.sw-media-preview-v2 img');

                if (mediaItem) {
                    htmlContent = htmlContent.replace(/{mediaUrl}/gi, mediaItem.src);
                }
            }

            if (!htmlContent) {
                this.createNotificationError({
                    title: 'Fehler',
                    message: 'Bitte gib den HTML-Inhalt ein.'
                });
                return;
            }
            
            this.$http.post('/api/v1/myplugin/create-pdf', { html: htmlContent })
                .then(response => {
                    const pdfData = response.data;
                    const blob = new Blob([pdfData], { type: 'application/pdf' });
                    const url = URL.createObjectURL(blob);

                    window.open(url, '_blank');
                })
                .catch(error => {
                    console.error(error);
                    this.createNotificationError({
                        title: 'Fehler',
                        message: 'Das PDF konnte nicht erstellt werden.'
                    });
                });
        }
    }
});

```

das ist der js-Code den ich anschließend mit build-administration.sh umwandle.

Wenn ich aber auf den Link klicke passiert nichts, in meiner Browser Konsole steht:

```auto
An error was captured in current module: TypeError: Cannot read properties of undefined (reading 'post')
    at Proxy.generatePdf (myplugin.js?1730830351:1:6788)
    at c.583802.n.<computed>.n.<computed> (app.js?1725261915:57:50736)
    at t2 (app.js?1725261915:45:664)
    at t5 (app.js?1725261915:45:732)
    at HTMLAnchorElement.n (app.js?1725261915:57:52359)

```

Mein Controller sieht so aus:

```auto
<?php declare(strict_types=1);

namespace MyPlugin\Controller;

use MyPlugin\Service\CreatePdfService;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Shopware\Core\Framework\Context;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;

class CreatePdfController extends AbstractController
{
    private CreatePdfService $createPdfService;

    public function __construct(CreatePdfService $createPdfService)
    {
        $this->createPdfService = $createPdfService;
    }

    #[Route(path: '/api/v{version}/myplugin/create-pdf', name: 'api.myplugin.create-pdf', methods: ['POST'], defaults: ['_routeScope' => ['admin']])]
    public function createPdf(Request $request): Response
    {
        $pdfData = $this->createPdfService->create($request->get('html'));
        //$pdfData = dompdf->output()
        return new Response($pdfData, 200, [
            'Content-Type' => 'application/pdf',
            'Content-Disposition' => 'inline; filename="preview.pdf"'
        ]);
    }
}

```

Ebenfalls denke ich das this.createNotificationError wohl dann auch nicht funktioniert.

Wäre super nett wenn mir jemand helfen könnte 🙂

---

<div class="post-metadata">

**Author:** ![StefP](https://avatars.discourse-cdn.com/v4/letter/s/8491ac/32.png) [@StefP](https://forum.shopware.com/u/StefP)\
**Post date:** [5. November 2024 um 21:09 UTC](https://forum.shopware.com/t/link-im-backend-soll-einen-post-befehl-ausfuehren/105758/2 "2024-11-05T21:09:25Z")

</div>

copy&paste ChatGPT

Ich sehe schon, das ist eine knifflige Stelle! Bei Shopware gibt es ein paar spezifische Eigenheiten, wenn man mit `this.$http` und solchen Benachrichtigungen in der Administration arbeitet. Ich helfe dir Schritt für Schritt herauszufinden, was da nicht klappt und wie du es zum Laufen bringen kannst. Lass uns die Sache angehen:

### Problemursache

Der Fehler `"Cannot read properties of undefined (reading 'post')"` deutet darauf hin, dass `this.$http` nicht initialisiert oder verfügbar ist. `this.$http` existiert in Shopware 6 Administration standardmäßig nicht als `$http`-Instanz. Stattdessen wird in Shopware 6 oft der `repositoryFactory` oder `axios` für HTTP-Requests verwendet.

Außerdem gibt es auch das Problem mit `this.createNotificationError`, das auch auf fehlende Shopware-Spezifikationen hinweist.

### Lösungsvorschlag: Alternative HTTP-Request Methode

Du kannst stattdessen `Shopware.Service('storeService')` nutzen, um den API-Call zu realisieren.

Hier eine angepasste Version des JavaScript-Codes:

javascript

Code kopieren

```auto
import template from './sw-product-detail-specifications.html.twig';

const { Component } = Shopware;

Component.override('sw-product-detail-specifications', {
    template,

    methods: {
        generatePdf() {
            let htmlContent = document.getElementById('MyPlugin_html').value;
            const mediaField = document.querySelector('sw-media-field[name="MyPlugin_img"]');

            if (mediaField) {
                const mediaItem = mediaField.querySelector('.sw-media-preview-v2 img');

                if (mediaItem) {
                    htmlContent = htmlContent.replace(/{mediaUrl}/gi, mediaItem.src);
                }
            }

            if (!htmlContent) {
                this.createNotificationError({
                    title: 'Fehler',
                    message: 'Bitte gib den HTML-Inhalt ein.'
                });
                return;
            }
            
            // Hier wird der alternative HTTP-Request verwendet
            Shopware.Service('storeService').httpClient.post(
                '/api/v1/myplugin/create-pdf',
                { html: htmlContent },
                { responseType: 'arraybuffer' }
            ).then(response => {
                const pdfData = response.data;
                const blob = new Blob([pdfData], { type: 'application/pdf' });
                const url = URL.createObjectURL(blob);

                window.open(url, '_blank');
            }).catch(error => {
                console.error(error);
                this.createNotificationError({
                    title: 'Fehler',
                    message: 'Das PDF konnte nicht erstellt werden.'
                });
            });
        }
    }
});

```

### Erklärung der Änderungen

1. **HTTP-Request** : Statt `this.$http.post` verwenden wir `Shopware.Service('storeService').httpClient.post`, was dem empfohlenen Weg für HTTP-Requests in der Administration entspricht.

- Beachte auch, dass `responseType: 'arraybuffer'` gesetzt wurde, damit die PDF-Daten im richtigen Format verarbeitet werden.

1. **Fehlerbenachrichtigungen** : Mit `this.createNotificationError` hast du den richtigen Ansatz gewählt, aber manchmal hilft es auch, das Notification-Plugin explizit zu importieren:

javascript

Code kopieren

```auto
const { Component, Mixin } = Shopware;

Component.override('sw-product-detail-specifications', {
    template,
    mixins: [Mixin.getByName('notification')],

```

Das Hinzufügen des Notification-Mixins sollte sicherstellen, dass `createNotificationError` verfügbar ist.

### Zusätzliche Hinweise

- Stelle sicher, dass der Endpunkt `'/api/v1/myplugin/create-pdf'` auch tatsächlich in deiner `services.xml` oder `routes.yaml` definiert ist, damit die Route funktioniert.
- Wenn du weiterhin Schwierigkeiten hast, prüfe, ob die Route auch den richtigen Zugriff hat (`_routeScope` auf `'admin'` setzen).
- Starte den Entwicklungsserver nach Änderungen am Plugin neu, damit alle Änderungen geladen werden.

Probier das mal aus, und melde dich, wenn weitere Fragen auftauchen oder noch andere Dinge nicht funktionieren! 😊
