předavaní dat mezi ajax a latte

vlkodlak
Člen | 165
+
0
-

zdravím,

před nějakou dobou jsem zkoušel komunikaci mezi JS a Latte a vše fungovalo, ale dnes …

...
    public function handleUserdata(array $param) {
        if ($this->isAjax()) {
            $this->payload->message = 'Success';
        }
    }
....

mám JS volani

....
    $('#AdminUserModal').on('show.bs.modal', function (event) {
        $.nette.ajax({
            type: 'post',
            url: '?do=Userdata',
            data: {
                param: {
                    aRecId: $(event.relatedTarget).data('bs-userid')
                }
            },
            success: function (payload) {
                console.log(payload);.........................vraci html stranku
                console.log(payload.message);..................vraci že není definovano
            },
        });
...

a aRecId je v pořádku předaná dovnitř, ale již zpět nedostávám message, jen celou vytvořenou html v payload

Editoval vlkodlak (14. 10. 2023 23:12)

vlkodlak
Člen | 165
+
0
-

RESENI „REBUSU“

    public function handleUserdata(array $param) {
        if ($this->isAjax()) {
            $this->payload->message = 'vlkodlak podruhe objevil ameriku';
            $this->sendPayload();
        }
    }

pak hodnota payload bude

{
 "message": "vlkodlak podruhe objevil ameriku",
  "state": []
}

Editoval vlkodlak (15. 10. 2023 0:03)

m.brecher
Generous Backer | 794
+
+1
-

@vlkodlak

RESENI „REBUSU“

Jak píšeš, bylo potřeba zavolat metodu $this->sendPayload(). Zajímalo mne, kde je to v dokumentaci k Nette Ajaxu uvedeno a nenašel jsem vůbec nic:

https://doc.nette.org/…ication/ajax

$this->payload->message je uvedeno v příkladu kódu: https://doc.nette.org/…ication/ajax#…

public function actionDelete(int $id): void
{
	if ($this->isAjax()) {
		$this->payload->message = 'Success';
	}
	// ...
}

Jak píšeš, že tam chyběla ta metoda $this->sendPayload(), tak si myslím, že by bylo vhodné ji do dokumentace doplnit a nějak popsat co dělá + přidat ji do toho příkladu kódu:

public function actionDelete(int $id): void
{
	if ($this->isAjax()) {
		$this->payload->message = 'Success';
        $this->sendPayload();
	}
	// ...
}

Podotýkám ale, že problematiku payload v Nette neznám a když jsem četl dokumentaci, tak jsem nabyl dojmu analogicky k automatickému odesílání latte šablon, že se payload také odesílá nějak podobně automaticky. Bylo by dobré, kdyby nějaký znalec ajaxového payload můj návrh potvrdil předtím, než bych podal do dokumentace PR.

Editoval m.brecher (15. 10. 2023 6:04)

Kcko
Člen | 465
+
0
-

m.brecher napsal(a):

@vlkodlak

RESENI „REBUSU“

Jak píšeš, bylo potřeba zavolat metodu $this->sendPayload(). Zajímalo mne, kde je to v dokumentaci k Nette Ajaxu uvedeno a nenašel jsem vůbec nic:

https://doc.nette.org/…ication/ajax

$this->payload->message je uvedeno v příkladu kódu: https://doc.nette.org/…ication/ajax#…

public function actionDelete(int $id): void
{
	if ($this->isAjax()) {
		$this->payload->message = 'Success';
	}
	// ...
}

Jak píšeš, že tam chyběla ta metoda $this->sendPayload(), tak si myslím, že by bylo vhodné ji do dokumentace doplnit a nějak popsat co dělá + přidat ji do toho příkladu kódu:

public function actionDelete(int $id): void
{
	if ($this->isAjax()) {
		$this->payload->message = 'Success';
        $this->sendPayload();
	}
	// ...
}

Podotýkám ale, že problematiku payload v Nette neznám a když jsem četl dokumentaci, tak jsem nabyl dojmu analogicky k automatickému odesílání latte šablon, že se payload také odesílá nějak podobně automaticky. Bylo by dobré, kdyby nějaký znalec ajaxového payload můj návrh potvrdil předtím, než bych podal do dokumentace PR.

@DavidGrudl Ti už několikrát psal, ať pošleš PR. Psal jsi mu, že s GIT-em neumíš, ale že to zkusíš. Už je to drahná doba.
Už jsi se to naučil?

Možná by bylo lepší poslat jeden PR, než plodit tuny textu – bez urážky.

Navíc, tato interakce přímo na Githubu je otázka chviličky.

nightfish
Člen | 480
+
+1
-

m.brecher napsal(a):
Podotýkám ale, že problematiku payload v Nette neznám a když jsem četl dokumentaci, tak jsem nabyl dojmu analogicky k automatickému odesílání latte šablon, že se payload také odesílá nějak podobně automaticky. Bylo by dobré, kdyby nějaký znalec ajaxového payload můj návrh potvrdil předtím, než bych podal do dokumentace PR.

@mbrecher
Relevantní kód v Presenteru: https://github.com/…resenter.php#L234

David Grudl
Nette Core | 8182
+
+3
-

Neposílej prosím PR, metodu není standardně potřeba volat, problém je někde jinde.

m.brecher
Generous Backer | 794
+
+1
-

@Kcko

Už jsi se to naučil?

Poslal jsem do dokumentace několik PR, ale po prvotních zkušenostech jsem opatrný, protože člověk od boku snadno napíše PR, kde je něco nedomyšleného, obzvláště pokud se doplňuje něco, co v dokumentaci chybí. Takže nechci posílat nedomyšlené PR, aby se zbytečně github dokumentace neznepřehledňoval.

mystik
Člen | 298
+
0
-

Payload by se mel poslat automaticky pokud tomu neco nezabrani. Co mas v action/render metodach ktere nasleduji po provedeni toho handle?

vlkodlak
Člen | 165
+
0
-

mystik napsal(a):

Payload by se mel poslat automaticky pokud tomu neco nezabrani. Co mas v action/render metodach ktere nasleduji po provedeni toho handle?

nic, jen promenou, kterou načtu z databaze

    public function renderDefault() {
        $this->template->dataMenu = $this->webFacade->getUserMenu($this->user->getIdentity()->getData()['IDrole']);
    }

  • jinak pro info @DavidGrudl, @mbrecher : cca před rokem jsem pracoval na zakázce, kde jsem též potřeboval pracovat s payloadem a nic nebylo potřeba měnit či nastavovat vše fungovalo přesně dle návodu na web stránce. Teď pomohlo jen přidáni $this->sendpayload dokonce, když jsem pokusil použit stejná rozšíření bootstrap 4.5.2, jquery-2.2.4.min.js … výsledek byl stejný v payload byla odeslaná jen sestavená web stránka a nic jiného …. přiznávám se, že to bylo již poté co jsem našel řešení a možná, že již jsem nebyl důsledný v testu.
  • A také doplním postřeh, že po aplikaci řešení ač mohu pracovat s předanou hodnotou tak console.log(payload.message); a console.log(payload[‚message‘]); mi nevypíše nic, což jsem čekal, že funguje na všech 100% za jakéhokoliv počasí, ale zas alert(payload.message); ano a dokonce alert(typeof(payload[‚message‘])); správně oznámí, že skutečně se jedna o stringovou hodnotu.
mystik
Člen | 298
+
0
-

To je divne to by melo fungovat i bez toho sendPayload. Metoda actionDefault neexistuje? Jeste by to mohly nejak ovlivnit osttani metody z lifecycle presenteru. Neukazal bys cely kod presenteru? Jestli tam treba nedelas nejaky redirect apod.

vlkodlak
Člen | 165
+
0
-

mystik napsal(a):

To je divne to by melo fungovat i bez toho sendPayload. Metoda actionDefault neexistuje? Jeste by to mohly nejak ovlivnit osttani metody z lifecycle presenteru. Neukazal bys cely kod presenteru? Jestli tam treba nedelas nejaky redirect apod.

declare(strict_types=1);

namespace App\Presenters;

use Nette;

final class AdminPresenter extends Nette\Application\UI\Presenter {

    public function beforeRender() {
        if (!$this->getUser()->isLoggedIn()) {
            $this->redirect('Sign:login');
        }
        $this->template->titlepage = $this->MySysDefinition->getValue("verze");
    }

    public function renderDefault() {
        $this->template->dataMenu = $this->webFacade->getUserMenu($this->user->getIdentity()->getData()['IDrole']);
    }

    public function renderUser() {
        $this->template->dataMenu = $this->webFacade->getUserMenu($this->user->getIdentity()->getData()['IDrole']);
        $this->template->listUsers = $this->webFacade->getAllUsers();
        $this->template->allroles = $this->webFacade->getAllRoles();
    }

    public function handleChangeswithvalue(array $param) {
        //bdump($param);
        $this->webFacade->onoffUser((int) $param['aRecId'], (int) ($param['aValue']));
        $this->redrawControl('adminListUsers');
    }

    public function handleAdminuserrefresh() {
        $this->redrawControl('adminListUsers');
    }

    public function handleUserdata(array $param) {
        //$this->payload->odpoved = 'prave jsem vratil data z handleru pro' . $param['aRecId'];

        if ($this->isAjax()) {
            $this->payload->message = 'vlkodlak podruhe objevil ameriku';
            $this->sendPayload();
        }
    }
}
Kamil Valenta
Člen | 771
+
0
-

Pokud console.log(payload.message); nefunguje a alert(payload.message); ano, hledal bych chybu v nevalidním frontendu. Nevypisuje se do konzole nějaký JS error, za kterým se to zařízne?

m.brecher
Generous Backer | 794
+
+1
-

@vlkodlak @DavidGrudl

Zkoušel jsem testovat jak funguje $this->payload a $this->sendJSON() když se pošle jednoduchý ajaxový signál pomocí javascript fetch api a objevil jsem nějaké chyby v odpovědi Nette. Přitom komunikace fetchAPI + sendJSON() mě v jiném projektu funguje – mám tam ale starší verze Nette.

<script>
    class Test
    {
        #signalUrl

        constructor(signalUrl){
            this.#signalUrl = window.location.origin + signalUrl
        }

        ping()
        {
            fetch(this.#signalUrl)
                .then(response => {
                    if(!response.ok){
                        throw new Error('network response not OK')
                    }
                    return response.json()
                })
                .then(jsonData => {
                    console.log(jsonData)
                    let data = JSON.parse(jsonData)
                    console.log(data)
                })
                .catch(error => console.error(error))
        }
    }
        const test = new Test({$presenter->link('ping!')})
        document.addEventListener('DOMContentLoaded', () => {
            document.getElementById('test-button').addEventListener('click', () => test.ping())
        })
    </script>

presenter:

public function handlePing()
{
    bdump($this->isAjax()); // první chyba - vrací false, přestože Tracy indikuje ajax request
}
public function handlePing()
{
    $this->payload->message = 'ahoj'; // SyntaxError: Unexpected token '<', "<!DOCTYPE
}
public function handlePing()
{
    $this->payload->message = 'ahoj';
    $this->sendPayload();    // SyntaxError: "[object Object]" is not valid JSON at JSON.parse
}
 public function handlePing()
{
   $this->sendJson(json_encode(['message' => 'ahoj']));  // funguje OK
}

Chyby jsem indikoval v úplně poslední verzi Nette:

latte/latte v3.0.9
nette/application v3.1.14
nette/bootstrap v3.2.1
nette/caching v3.2.2
nette/component-model v3.0.3
nette/database v3.1.7
nette/di v3.1.5
nette/finder v3.0.0
nette/forms v3.1.12
nette/http v3.2.2
nette/mail v4.0.1
nette/neon v3.4.1
nette/php-generator v4.1.0
nette/robot-loader v4.0.1
nette/routing v3.0.5
nette/schema v1.2.5
nette/security v3.1.7
nette/utils v4.0.2
tracy/tracy v2.10.4

Ve stejné verzi Nette používám ajaxove Nette Snippety + Naja a to funguje výtečně.

Takže to vypadá, že možná v nejnovější verzi Nette vznikly nějaké chyby v komunikaci při použití sendJSON, payload a vyhodnocení požadavu javascriptu pomocí fetchAPI. Používám prohlížeč Chrome.

@vlkodlak

již zpět nedostávám message, jen celou vytvořenou html v payload

Ano, to potvrzuje i můj test. Zkus místo toho odeslat data pomocí $this->sendJson(json_encode([‚message‘ ⇒ ‚ahoj‘])), to by fungovat mělo a popř. vynechat if($this->isAjax())

Editoval m.brecher (15. 10. 2023 21:03)

vlkodlak
Člen | 165
+
0
-

m.brecher napsal(a):
@vlkodlak

již zpět nedostávám message, jen celou vytvořenou html v payload

Ano, to potvrzuje i můj test. Zkus místo toho odeslat data pomocí $this->sendJson(json_encode([‚message‘ ⇒ ‚ahoj‘])), to by fungovat mělo a popř. vynechat if($this->isAjax())

děkují

vlkodlak
Člen | 165
+
0
-

Kamil Valenta napsal(a):

Pokud console.log(payload.message); nefunguje a alert(payload.message); ano, hledal bych chybu v nevalidním frontendu. Nevypisuje se do konzole nějaký JS error, za kterým se to zařízne?

ano úvaha spravná, ale bylo to první co jsem zkoumal, když jsem „nedostal“ požadovanou odpověď

David Grudl
Nette Core | 8182
+
+3
-

Pokud používáš fetch(), musíš poslat i hlavičku ‚X-Requested-With‘: ‚XMLHttpRequest‘

vlkodlak
Člen | 165
+
0
-

David Grudl napsal(a):

Pokud používáš fetch(), musíš poslat i hlavičku ‚X-Requested-With‘: ‚XMLHttpRequest‘

promin, nerozumim tvé nápovedě
Ajax → Presenter … vse funguje
Presenter → ajax … v promene payload dojde ke ztrate vlozene hodnoty, jak mam rici nette aby $this->payload->message … odeslal viz tvuj popis?

David Grudl
Nette Core | 8182
+
+2
-

To patřilo @mbrecher, sry.

Jinak v Nette se nic neměnilo, takže zkus hledat chybu někde jinde.

mystik
Člen | 298
+
0
-

@vlkodlak To nebude uplne cely kod presenteru ne? Nebo kde se vezmou veci jako $this->webFacade?

vlkodlak
Člen | 165
+
0
-

mystik napsal(a):

@vlkodlak To nebude uplne cely kod presenteru ne? Nebo kde se vezmou veci jako $this->webFacade?

co treba jako sluzba prilinkovana pres konstruktor?

    public function __construct(
			...
            protected \App\Model\webFacade $webFacade,
			...
    ) {
        parent::__construct();
    }

a pak samotny kod webFacade

namespace App\Model;

use Nette;

final class webFacade {
	....
    public function getAllUsers() {
        $sqlData = $this->database->fetchAll('
			....
        ');

        $sqlData = json_decode(json_encode($sqlData), true);

        return $sqlData;
    }
	...
    public function getUserMenu($userIdRole = -1) {
        $sqlData = $this->database->fetchAll('
 			...
        ');

        $sqlData = json_decode(json_encode($sqlData), true);

        return $sqlData;
    }
	...
}

byt nechapu jak to souvisi s odeslanim textove hodnony pres ajax … k „chybe“ dochazi zde a je uplne jedno zda hodnota nactena z databaze nebo jen pridana rucne

    public function handleUserdata(array $param) {
        if ($this->isAjax()) {
            $this->payload->message = 'vlkodlak podruhe objevil ameriku';
        }
    }

Editoval vlkodlak (16. 10. 2023 1:36)

mystik
Člen | 298
+
+2
-

Jde o to ze pokud nevidim opravdu uplne cely kod presenteru, tak nemuzu vyloucit moznost, ze se tam nekde v castech cos neposlal, dela neco co zpusobuje tu chybu. K te chybe nedochazi tam co pises ale tesne pred koncem lifecycle, kde se ma payload poslat automaticky. Pokud k tomu nedojde tak pravdepodobne neco zmenilo stav presenteru tak ze payload neposle.

vlkodlak
Člen | 165
+
0
-

mystik napsal(a):

Jde o to ze pokud nevidim opravdu uplne cely kod presenteru, tak nemuzu vyloucit moznost, ze se tam nekde v castech cos neposlal, dela neco co zpusobuje tu chybu. K te chybe nedochazi tam co pises ale tesne pred koncem lifecycle, kde se ma payload poslat automaticky. Pokud k tomu nedojde tak pravdepodobne neco zmenilo stav presenteru tak ze payload neposle.

ještě mně napadlo, zda lzé v consoli vidět zda payload není pole … hloupost, ale mám pocit, že v prvních dnech snahy o pochopení jsem zahledl neco s payloadem … ale jak už to bývá podruhe jsem to již nedohledal, lze vytahnout / prohledat celý balik dat/komunikace fultextově?

mskocik
Člen | 57
+
+1
-

@vlkodlak mozno trochu offtopic, ale preco si to neodkrokujes cez xdebug? Tak rychlo zistis, kde ti to zlyhava.

vlkodlak
Člen | 165
+
0
-

mskocik napsal(a):

@vlkodlak mozno trochu offtopic, ale preco si to neodkrokujes cez xdebug? Tak rychlo zistis, kde ti to zlyhava.

protože, nápad dobrý a lákavý, ale při pokusu o spuštění xdebugu mi to skonči u waiting for conection … ano, něco není spuštěno … pravděpodobně xdebug … zatim není časový prostor k odladění … klasický kovařová kobyla

Editoval vlkodlak (16. 10. 2023 13:52)

nightfish
Člen | 480
+
+2
-

vlkodlak napsal(a):
ještě mně napadlo, zda lzé v consoli vidět zda payload není pole … hloupost, ale mám pocit, že v prvních dnech snahy o pochopení jsem zahledl neco s payloadem … ale jak už to bývá podruhe jsem to již nedohledal, lze vytahnout / prohledat celý balik dat/komunikace fultextově?

V prohlížeči si otevři Developer Tools, záložku Network, najdi si svůj AJAX požadavek (buď pomocí filtru a nebo pohledem), rozklikni jej a uvidíš data požadavku i odpovědi.

vlkodlak
Člen | 165
+
0
-

nightfish napsal(a):

vlkodlak napsal(a):
ještě mně napadlo, zda lzé v consoli vidět zda payload není pole … hloupost, ale mám pocit, že v prvních dnech snahy o pochopení jsem zahledl neco s payloadem … ale jak už to bývá podruhe jsem to již nedohledal, lze vytahnout / prohledat celý balik dat/komunikace fultextově?

V prohlížeči si otevři Developer Tools, záložku Network, najdi si svůj AJAX požadavek (buď pomocí filtru a nebo pohledem), rozklikni jej a uvidíš data požadavku i odpovědi.

pokud si dohledám typ komunikace xhr, vidím zavolaní handleru i s předanou hodnotou, a pote návratová hodnota payload je web stránka, po použiti $this->sendPayload(); vidím pole a vše co do něj vkládám

mystik
Člen | 298
+
+2
-

Koukni na misto v Presenter co vyse linkoval @nightfish a dumpni si tam hodnoty co overuje ten if ktery urcuje zda se sendPayload zavola automaticky. Podle toho muzem zacit hledat co to zpusobi.

vlkodlak
Člen | 165
+
0
-

mystik napsal(a):

Koukni na misto v Presenter co vyse linkoval @nightfish a dumpni si tam hodnoty co overuje ten if ktery urcuje zda se sendPayload zavola automaticky. Podle toho muzem zacit hledat co to zpusobi.

dobře, zde (https://github.com/…resenter.php#L234) to je ještě v pořadku, pole přesně dle očekavání. Pak si to někde přepiši :-S … ale nic umyslněho nedělam :-(

mystik
Člen | 298
+
+1
-

Jde o to zda se ti tam vola to sendPayload ne jestli mas v tom poli spravna data. Protoze to vypada ze se to nezavola.

vlkodlak
Člen | 165
+
0
-

mystik napsal(a):

Jde o to zda se ti tam vola to sendPayload ne jestli mas v tom poli spravna data. Protoze to vypada ze se to nezavola.

dobre, chyba mezi klavesnici a zidli vypada to na to ze $this->isAjax()=false ??? ale jak to kdyz v handleru je stejna podminka a hodnoty se mi predaji, stranka se prekresli … jako kdybych volal nette.init se spozdenim

mystik
Člen | 298
+
0
-

Takze isAjax ti v handkeru vraci true ale na tom miste uz false? To by melo byt nemozne. Tam bude nejaka zrada kterou prehlizime. Urcite to je v ramci stejneho requestu? Neni tam tech requestu vic? Nejake presmerovani? Nebo tak?

vlkodlak
Člen | 165
+
0
-

mystik napsal(a):

Takze isAjax ti v handkeru vraci true ale na tom miste uz false? To by melo byt nemozne. Tam bude nejaka zrada kterou prehlizime. Urcite to je v ramci stejneho requestu? Neni tam tech requestu vic? Nejake presmerovani? Nebo tak?

Zjistil jsem, že aktivitu, pravděpodobně, s předaním hodnot prezenteru tvořím dřív než je aktivovano nette, protože v dalšich krocich nette je již aktivní … tj řešením asi je buď ponechat $this->sendPayload(); nebo odsunout proces předaní dat z adminPresenteru do jiné časti kodu

Editoval vlkodlak (17. 10. 2023 11:55)

m.brecher
Generous Backer | 794
+
+1
-

Zkoušel jsem přijít na to, co způsobuje chyby v komunikaci javascript fetchAPI s Nette při použití vestavěného objektu payload, které jsem popsal zde: https://forum.nette.org/…ajax-a-latte#…

a) aby metoda $this->isAjax() vracela správnou hodnotu, musí se na straně javascriptu nastavit http hlavička ‚X-Requested-With‘: ‚XMLHttpRequest‘ (fetchAPI i XMLHttpRequest)

b) payload při komunikaci s vlastním javascriptem (fetchAPI, XMLHttpRequest) se automaticky neodešle i když se přidají http hlavičky, které přidává knihovna Naja, když se ručně zavolá $this->sendPayload() je po problému

c) fetchAPI při zpracování response z Nette payload hlásí nevalidní JSON, což lze ale vyřešit použitím response.text() místo response.json()

fetch(this.#dataUrl,{
    method: 'GET',
    headers: {  // přidat hlavičky jako Naja nepomůže automaticky odeslat payload z Nette
        'X-Requested-With': 'XMLHttpRequest',
        'accept': 'application/json',
    }
})
    .then(response => {
        return response.text();  // funguje s Nette sendPayload()
        // return response.json();  // nefunguje s Nette sendPayload()
    })
    .then(jsonData => {
        console.log(JSON.parse(jsonData))
    })

Otázkou zůstává, co všechno má být v kódu splněno, aby automatické odesílání payload fungovalo?? Není lepší metodu sendPayload() v dokumentaci uvést (nyní chybí) a dát ji i do příkladu s $this->payload, kde jak testy ukázaly automatické odeslání není spolehlivé??

David Grudl
Nette Core | 8182
+
+1
-

@mbrecher to co popisuješ není standardní a očekávané chování. Ani jsem se nikdy s takovým chováním nesetkal, takže nevím, proč se to děje. Bude užitečné, pokud to nějak vyzkoumáš.

Ve tvém prohlížeči nefunguje ani Fifteen? Selhává tam taky response.json?

mskocik
Člen | 57
+
0
-

@mbrecher a máš repo, kde ti nefunguje minimálny príklad z dokumentácie (Keď pominieme „automatické odosielanie“) Ja osobne nedokážem zreprodukovať čo píšeš.

fetch(url, {
	headers: {'X-Requested-With': 'XMLHttpRequest'},
})
.then(response => response.json())
.then(payload => {
	// zpracování odpovědi
});

Nette automaticky odosiela payload len v prípade invalidných snippetov – čo dáva zmysel, lebo ajaxovým requestom na signál asi väčšinou chceš updatnúť nejaký snippet.

Pokiaľ máš v pláne posielať JSON, tak zavoláš $presenter->sendPayload() alebo $presenter->sendJson($data) už v handle metóde, nie?

m.brecher
Generous Backer | 794
+
+2
-

@DavidGrudl

response.json() funguje pro sendPayload() i sendJSON()

fetch(this.#dataUrl)
    .then(response => response.json())
    .then(payload => console.log(payload))

Měl jsem v kódu chybu – nadbytečné kódování do JSON v sendJson() a následně ve fetch() dvojí dekódování z JSON:

$this->sendJson(json_encode(['message' => 'ahoj']));  // moje chyba - nadbytečný json_encode()

selhání automatického odeslání payload

Toto je záhada, otestoval jsem prohlížeč Google Chrome i MS Edge a na domácím Windows/Apache instalaci serveru i na webhostingu s Linuxem, poslední verzi Nette i cca rok starou – všude stejný výsledek:

    public function handlePing()
    {
        $this->payload->message = 'ahoj';  // vrací HTML stránku
//        $this->sendPayload();
    }
    public function handlePing()
    {
        $this->payload->message = 'ahoj';
        $this->sendPayload();             // vrací JSON
    }

Kde by tedy mohla být chyba, kterým směrem pátrat dál?

EDIT – doplněno

@mskocik doplňuje důležitou informaci „Nette automaticky odosiela payload len v prípade invalidných snippetov“ a „Pokiaľ máš v pláne posielať JSON, tak zavoláš $presenter->sendPayload()“

Takže pokud tomu tak je, potom by bylo vhodné použití $presenter->payload a $presenter->sendPayload() nějak srozumitelně doplnit do dokumentace o AJAXu.

Editoval m.brecher (17. 10. 2023 21:09)

m.brecher
Generous Backer | 794
+
+1
-

@mskocik

Nette automaticky odosiela payload len v prípade invalidných snippetov

Díky za info, protože to přispívá podstatně k vyřešení problému. Zatím zde byly tvrzení, že se payload odesílá automaticky a tudíž není vhodné do ukázky kódu v dokumentaci doplňovat metodu $this->sendPayload().

Pokud máš pravdu, tak potom chyba „selhání automatického odeslání payloadu“ není chyba, ale žádoucí chování Nette. Bylo by ale dobré toto nějak doplnit do dokumentace, protože tohle se tam v úvodu do kapitoly AJAX a Snippety dohledat nedá. Metoda $this->sendPayload() tam kupříkladu není vůbec uvedená.

Pokiaľ máš v pláne posielať JSON, tak zavoláš $presenter->sendPayload() alebo $presenter->sendJson($data) už v handle metóde, nie?

Samozřejmě, používám metodu $presenter->sendJson($data) tam žádný problém není.

mskocik
Člen | 57
+
+2
-

m.brecher napsal(a):

Pokud máš pravdu, tak potom chyba „selhání automatického odeslání payloadu“ není chyba, ale žádoucí chování Nette.

Stačí sa pozrieť do kódu presenteru, ako handluje ajax:

if ($this->isAjax()) {
	$this->payload->state = $this->getGlobalState();
	try {
		if ($this->response instanceof Responses\TextResponse && $this->isControlInvalid()) {
			$this->snippetMode = true;
			$this->response->send($this->httpRequest, $this->httpResponse);
			$this->sendPayload();
		}
	} catch (Application\AbortException $e) {
	}
}

A vidíš, že Nette odošle automaticky payload, len ak je response typu TextResponse (default) a nejaký snippet/komponenta je invalidná, tj. niekde sa volala metóda redrawControl().
Ak tento if neprebehne, kód pokračuje klasickým spôsobom, tj. renderuje kompletnú šablónu.

Súhlasím s tým, že dokumentáciá nie je jasná na 100%. V praxi sa často stretávam s tým, že problematike ajax+snippety veľa ľudí nerozumie a tým pádom nevedia, akým skvelým nástrojom snippety sú. Možno by bolo vhodné dokumentáciu upraviť v zmysle, že primárne sa tam rozoberajú snippety. A až následne sendJson a sendPayload metódy.

Editoval mskocik (18. 10. 2023 11:43)