0

I am trying to display records from query in a table and on button clicked to make an ajax call to download the information in an xml format. The query is executed from method inside a class and the ajax request makes call to a different method inside the same class. The first method fills two private properties inside the class and the second property(the one called through the ajax request) must read the properties and fill the data inside table and make the file downloadable. When I try to read the properties from the same class though I get nulls and the foreach returns an error.

This is my ajax request(downloaderScript.js):

;
    $("#downloadBtn").click(function (event) {
        event.preventDefault();
        event.stopPropagation();
        $.ajax({
            url: 'allClients.php',
            type: 'post',
            data: {action: 'downloader'},
            complete: function (result) {
                console.log(result);
            },
            error: function () {
                console.log('Error');
            }
        });
    });

This is the class from which I call the first and the second methods:

class HttpHandlerClient extends HttpHandlerAbstract
{
    private $clientsService;
    public $storedClientsHeadings;
    public $storedClientsData;

public function viewAllClients()
    {
        $data = $this->clientsService->getAllClients(clientEntity::class);
        if(isset($data)) {
            $this->storedClientsHeadings = ["Client Names:", "Delivery Address:", "Phone number:"];
            $this->storedClientsData = $data;
            $this->render('allClientsView', $data);
        }
        else
        {
            $this->redirect('clientAdd');
        }

    }

public function downloader()
    {
        header("Content-Type: text/plain");
        var_dump($this->storedClientsHeadings);
        foreach ($this->storedClientsHeadings as $arrayName)
        {
            echo implode("\t", $arrayName)."\r\n";
        }
        /**
         * @var clientEntity $clientData
         */
        foreach ($this->storedClientsData as $clientData)
        {
            echo implode("\t", $clientData->getClientName())."\r\n";
            echo implode("\t", $clientData->getAddressForDelivery())."\r\n";
            echo implode("\t", $clientData->getPhone())."\r\n";
        }
        $filename = "clients_".date("Y-m-d").".xls";
        header("Content-Disposition:attachment; filename=\"$filename\"");
        header("Content-Type: application/vnd.ms-excel");
    }

And this is the php file that i use between my ajax request and the php class(The file name is: allClients.php, in common.php I make an instance of the class HttpHandlerClient):

require_once 'common.php';

if(isset($_POST['action'])){
    $myHttpHandlerClient->downloader();
} elseif (isset($_GET['typer'])) {
    $myHttpHandlerClient->viewClientByNumber($_GET['typer']);
} else {
    $myHttpHandlerClient->viewAllClients();
}

Sorry if my question is trivial, I even started doubting that after require_once I re-run the code in common.php, making a new instance of HttpHandlerClient and because of this I get nulls in the properties. But when I was reading the documentation in php's site I did not read such a thing. Any help will be appreciated, thanks.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Ivanp
  • 425
  • 7
  • 18
  • 2
    Unless you're using sessions, each request knows nothing about the previous or (potential) next request. This is the essence of what makes HTTP [stateless](https://stackoverflow.com/questions/13200152/why-is-it-said-that-http-is-a-stateless-protocol) – Patrick Q Nov 26 '19 at 13:16
  • @PatrickQ Do not mind the requests, I am trying to get info from the same class as you can see from $myHttpHandlerClient->downloader(); I can guarantee that $myHttpHandlerClient->viewAllClients(); is ran first. The problem is that I set the properties once, but when I access the same instance of the class I do not get result from the properties. – Ivanp Nov 26 '19 at 13:34
  • 3
    That is because you are trying to "access the same instance" from a different request (the ajax request). This request knows nothing about what you've done before. "The query is executed from method inside a class" That is done to generate the content displayed on the page, correct? "the ajax request makes call to a different method inside the same class" That is then done on click of a certain element on the page, correct? Those are _two different_ requests, do you _need to_ "mind the requests". – Patrick Q Nov 26 '19 at 13:38
  • So the solution is either session_start() or I make second sql query inside the downloader. Thank you for the explanation. – Ivanp Nov 26 '19 at 13:43
  • Correct. I would probably pass an id in the ajax request and use that id to look up the desired data in the database. – Patrick Q Nov 26 '19 at 13:46

1 Answers1

0

It sounds like what may be happening is that there is a disconnect between the javascript initially loading and then more markup being added to the DOM.

  1. The page loads up which runs your javascript. At this point the JS only knows what is currently on the page.
  2. Your make the first call which changes the DOM. Your javascript does not know about these changes.
  3. You try to reference something that has not been recognized by your initial load of the Javascript.

After you make the call that changes the DOM, you may have to reinitialize your JS to recognize the changes.

Good luck