Jump to content

Fetch Response is drive me crazy 🤪


Strider64
Go to solution Solved by Barand,

Recommended Posts

I normally don't ask for help but this problem is driving me crazy.

I'm using plain Vanilla JS and use FETCH to retrieve a bunch of information for my photo gallery . https://phototechguru.com/gallery.php

It works fine in Firefox, but not Chrome or Safari. In the later two browsers I am getting this error message.

Database Table did not load SyntaxError: Unexpected token < in JSON at position 0

I will try to give the code I think that is important - here's some of the vanilla javascript

    /* create FETCH request */
    const createRequest = (url, succeed, fail) => {
        let cat = {}
        cat.category = category.value;
        console.log(category.value);
        console.log('cat',cat);
        fetch(url, {
            method: 'POST', // or 'PUT'
            body: JSON.stringify(cat)
        })
            .then((response) => handleErrors(response))
            .then((data) => succeed(data))
            .catch((error) => fail(error));
    };

    function selection(category) {
        /* Remove Image For Screen (cleanup) */
        while (container.firstChild) {
            container.removeChild(container.firstChild)
        }


        let url = 'galleryImagesGet.php';
        //let url =  urlRequest +  "category=" + category;

        createRequest(url, categoryUISuccess, categoryUIError);
    }
    category.addEventListener('change', () => { selection(category.value) } , false);
    category.value = 'general';
    createRequest('galleryImagesGet.php' , categoryUISuccess, categoryUIError);
})();

the galleryImagesGet.php

<?php

require_once 'assets/config/config.php';
require_once "vendor/autoload.php";

use PhotoTech\CMS;
use PhotoTech\Pagination_New as Pagination;
$cat = [];
/* Makes it so we don't have to decode the json coming from javascript */
header('Content-type: application/json');
/*
 * The below must be used in order for the json to be decoded properly.
 */
try {
    $cat = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
}

if ($cat['category'] === $_SESSION['category'] && isset($_SESSION['category'])) {
    $_SESSION['current_page'] + 1;
} elseif (!isset($cat['category'])) {
    $_SESSION['category'] = $cat['category'];
    $_SESSION['current_page'] = 1;
} else {
    $_SESSION['category'] = $cat['category'];
    $_SESSION['current_page'] = 1;
}


$per_page = 12; // Total number of records to be displayed:
$total_count = CMS::countAllPage('blog', $_SESSION['category']); // Total Records in the db table:

/* Send the 3 variables to the Pagination class to be processed */
$pagination = new Pagination($_SESSION['current_page'], $per_page, $total_count);

/* Grab the offset (page) location from using the offset method */
$offset = $pagination->offset();

/*
 * Grab the data from the CMS class method *static*
 * and put the data into an array variable.
 */
$cms = CMS::page($per_page, $offset, 'blog', $_SESSION['category']);
output($cms);

function output($output): void
{
    http_response_code(200);
    try {
        echo json_encode($output, JSON_THROW_ON_ERROR);
    } catch (JsonException) {
    }

}

I have tried Googling to find the solution and tried some of them, but I'm not to familiar with some of the terminology and I haven't gone too in-depth with the console for debugging. I can show more code if needed.  What's really puzzling is why will work in Firefox and not other browsers? 🤔 I don't know if this what put in the right forum category?

Edited by Strider64
Link to comment
Share on other sites

40 minutes ago, requinix said:

The error message is telling you that the first character in the "JSON" is a less-than. You know, like the kind used by HTML?

Doesn't that make you wonder what the "JSON" you expected to see, actually was?

I am definitely going crazy as I know can't get it the database to load whereas before I could. Before this latest fiasco of mine I did what they said to do.

    /* create FETCH request */
    const createRequest = (url, succeed, fail) => {
        let cat = {category: category.value}
        cat.category = category.value;
        console.log(category.value);
        console.log('cat',cat);
        fetch(url, {
            method: 'POST', // or 'PUT'
            body: JSON.stringify(cat)
        })
            //.then((response) => handleErrors(response))
            .then(res => res.text())          // convert to plain text
            .then(text => console.log(text))
            .then((data) => succeed(data))
            .catch((error) => fail(error));
    };

Now I get this gobbly  gook on all browsers

<br />
<b>Warning</b>:  Undefined array key "category" in <b>/homepages/11/d329291176/htdocs/phototech/galleryImagesGet.php</b> on line <b>19</b><br />
[{"id":171,"user_id":2,"author":"John Pepp","page":"blog","category":"general","image_path":"assets\/uploads\/img-gallery-

It's obvious that it's the first two lines of the mess. But how would I fix it? It used to work with it on Firefox, but I restarted my computer and now it say is doesn't load. Even though I did do a re-hard set time when I made modifications in Firefox, but at least Chrome is still giving me that error. So at least I am just semi-crazy.

 

BTW - Thanks for helping

Link to comment
Share on other sites

I am not familiar with the new JS code you are showing so I'll skip that, but you posted php code has some issues.

(in php mode)
require_once 'assets/config/config.php';
require_once "vendor/autoload.php";
use PhotoTech\CMS;
use PhotoTech\Pagination_New as Pagination;
$cat = [];
/* Makes it so we don't have to decode the json coming from javascript */
header('Content-type: application/json');
/*
* The below must be used in order for the json to be decoded properly.
*/
try 
{
	$cat = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR);
} 
catch (JsonException $e) 	// LINE MISSING SOMETHING
{
}

if ($cat['category'] === $_SESSION['category'] && isset($_SESSION['category'])) 
{
	$_SESSION['current_page'] + 1;	//  WHAT IS THIS LINE DOING?
} 
elseif (!isset($cat['category'])) 
{
	$_SESSION['category'] = $cat['category'];
	$_SESSION['current_page'] = 1;
} 
else 
{
	$_SESSION['category'] = $cat['category'];
	$_SESSION['current_page'] = 1;
}
$per_page = 12; // Total number of records to be displayed:
$total_count = CMS::countAllPage('blog', $_SESSION['category']); // Total Records in the db table:

/* Send the 3 variables to the Pagination class to be processed */
$pagination = new Pagination($_SESSION['current_page'], $per_page, $total_count);

/* Grab the offset (page) location from using the offset method */
$offset = $pagination->offset();

/*
* Grab the data from the CMS class method *static*
* and put the data into an array variable.
*/
$cms = CMS::page($per_page, $offset, 'blog', $_SESSION['category']);
output($cms);
//**********************************
function output($output): void
{
	http_response_code(200);
	try 
	{
		echo json_encode($output, JSON_THROW_ON_ERROR);
	} 
	catch (JsonException) 	// LINE MISSING A COUPLE OF SOMETHINGS
	{
	}
}

You s/b getting some error messages from my noted spots.

Link to comment
Share on other sites

  • Solution
5 hours ago, Strider64 said:
if ($cat['category'] === $_SESSION['category'] && isset($_SESSION['category'])) {
    $_SESSION['current_page'] + 1;
} elseif (!isset($cat['category'])) {
    $_SESSION['category'] = $cat['category'];
    $_SESSION['current_page'] = 1;
} else {
    $_SESSION['category'] = $cat['category'];
    $_SESSION['current_page'] = 1;
}

That above section of code is totally FUBAR

  • You test the value of $cat['category'] and afterwards decide to see if it is set!
  • Then having found it isn't set, you allocate this non-existant variable value to $_SESSION['category'].
  • Like 1
Link to comment
Share on other sites

1 hour ago, Barand said:

That above section of code is totally FUBAR

  • You test the value of $cat['category'] and afterwards decide to see if it is set!
  • Then having found it isn't set, you allocate this non-existant variable value to $_SESSION['category'].

Yes, It is after monkeying around with it for almost a day I simplified things and came up with this - I still think it can be better.

$data = [];
/*
 * The below must be used in order for the json to be decoded properly.
 */
try {
    $data = json_decode(file_get_contents('php://input'), true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
}

//echo "<pre>" . print_r($data['category'], 1) . "</pre>";
//die();

if (isset($_SESSION['category']) && $data['category'] === $_SESSION['category']) {
    $_SESSION['current_page'] += 1;
}  else {
    unset($_SESSION['category']); // This probably isn't even needed? 
    $_SESSION['category'] = $data['category'];
    $_SESSION['current_page'] = 1;
}

I will find out when I have more images or have less per page and have my links working in JavaScript (Which I probably should break this down even further?).

 

Thanks John

Edited by Strider64
Link to comment
Share on other sites

21 minutes ago, requinix said:

Is it me or are you doing pagination using session variables?

Well, I originally had pagination done in PHP, but I am in the process of converting it over to JavaScript. I'm more of a PHP person, but I like the fact Vanilla JavaScript doesn't reload the page. I was thinking of doing the links still in PHP, but I'm going to get around to doing it JavaScript. I was was thinking of just using sessions variables as a temporary fix, but if it cause this much of headache I probably just do it in Vanilla JS. Though I  hate the thoughts of doing the links in JavaScript. 🤔🤣 I know there is way of preloading a certain amount of images  in JavaScript which would be an idea solution, but I don't know how to go about to do it?

Edited by Strider64
Link to comment
Share on other sites

8 minutes ago, Strider64 said:

Well, I originally had pagination done in PHP, but

"Session variables" isn't a language. The choice is not "session variables instead of PHP" or "session variables instead of Javascript". The choice isn't even "PHP or Javascript".

The choice is "session variables or data in the request". As in you can decide to put page information into the session or you can put page information into the URL. And the latter is better.

Link to comment
Share on other sites

8 minutes ago, requinix said:

"Session variables" isn't a language. The choice is not "session variables instead of PHP" or "session variables instead of Javascript". The choice isn't even "PHP or Javascript".

The choice is "session variables or data in the request". As in you can decide to put page information into the session or you can put page information into the URL. And the latter is better.

That what I was trying to get at when I said preloading the images (like Flicker, Facebook and other websites do) just didn't know the terminology. I am a photographer that I want to share my best photographs on my own website, but even then I will still have a lot of images. I know sessions isn't going to cut it, so putting it in the URL is better though I will need a way not to load all my images onto the website hence the pagination. I will figure it out, probably combing the both. The URL for the images and the data for the sessions? I know I can use REACT or other Frameworks/Libraries, but I like doing it from scratch. I like the challenge for the most part and I like coding when I'm not taking photographs.

Link to comment
Share on other sites

Thanks to the help here, I think I am on the right path with my pagination and selecting categories.  While I'm not done coding I believe this is a much better way of doing it than using sessions thanks to requinix.

This is what I have here so far for the vanilla JavaScript:

'use strict';
(function () {
    let d = document;
    let category = d.querySelector('#category');
    let container = d.querySelector('.container');
    let sidebar = d.querySelector('.sidebar');
    let url = 'galleryImagesGet.php';
    let current_page = 1, per_page =6, offset = 0;
    let database_data = {'category':'general', 'current_page': current_page, 'per_page': per_page, 'total_count': 0, 'offset': offset };
    let pages = [{}];
    let total_pages = 0;

    const links = d.createElement('div');
    links.className = 'links';
    links.textContent = 'SIDEBAR';
    sidebar.appendChild(links);

    /* Handle General Errors in Fetch */
    const handleErrors = function (response) {
        if (!response.ok) {
            throw (response.status + ' : ' + response.statusText);
        }
        return response.json();
    };

    /*
     * FETCH for New Category
     */
    const categoryUISuccess = (parsedData) => {
        /* Remove Image For Screen (cleanup) */
        while (container.firstChild) {
            container.removeChild(container.firstChild)
        }
        console.log('parsed_data ', parsedData);
        console.log('pages', pages);

        let count = 0; // For different class names for size boxes in CSS

        parsedData.forEach(slide => {
            /* Main Image Slide Block */
            let displayDiv = d.createElement('div');
            /* Array of different size class names for CSS */
            let displayFormat = ["gallery-container w-4 h-2", 'gallery-container w-3 h-2', 'gallery-container w-4 h-2', 'gallery-container w-3 h-2', 'gallery-container w-3 h-2', 'gallery-container w-2 h-2', 'gallery-container h-2', 'gallery-container h-2', 'gallery-container w-2 h-2', 'gallery-container h-2', 'gallery-container w-2 h-2', 'gallery-container w-4 h-2',
                "gallery-container w-4 h-2", 'gallery-container w-3 h-2', 'gallery-container w-4 h-2', 'gallery-container w-3 h-2', 'gallery-container w-3 h-2', 'gallery-container w-2 h-2', 'gallery-container h-2', 'gallery-container h-2', 'gallery-container w-2 h-2', 'gallery-container h-2', 'gallery-container w-2 h-2', 'gallery-container w-4 h-2'];
            displayDiv.className = `${displayFormat[count]}`; //Assign Class Names to Div:
            container.appendChild(displayDiv); //Append Child to Parent Div:

            /*
             * Create div for indiviual images
             */
            let galleryItem = d.createElement('div');
            galleryItem.classList.add('gallery-item');
            displayDiv.appendChild(galleryItem);
            /*
             * Image div element
             */
            let images = d.createElement('div');
            images.classList.add('images');
            galleryItem.appendChild(images);
            /*
             * Image itself
             */
            let galleryImage = d.createElement('img')
            //console.log(slide.image_path);
            galleryImage.src = slide.image_path;
            galleryImage.setAttribute('alt', slide.content); // Description of what image is about:
            /* Set EXIF info to data-exif attribute */
            galleryImage.setAttribute('data-exif', slide.Model + ' ' + slide.ExposureTime + ' ' + slide.Aperture + ' '
                + slide.ISO + ' ' + slide.FocalLength);
            images.appendChild(galleryImage); // Append image to Image div element:
            /*
             * Hidden Paragraph
             */
            let paragraph = d.createElement('p');
            paragraph.classList.add('hideContent');
            paragraph.textContent = slide.content;
            images.appendChild(paragraph);
            /*
             * Title Block
             */
            let title = d.createElement('div');
            title.classList.add('title');
            galleryItem.appendChild(title);
            /*
             * Heading 1
             */
            let heading1 = d.createElement('h1');
            heading1.classList.add('pictureHeading');
            heading1.textContent = `${slide.heading[0].toUpperCase()}${slide.heading.slice(1)}`;
            title.appendChild(heading1);
            let titleSpan = d.createElement('span');
            titleSpan.classList.add('exifInfo');
            titleSpan.textContent = slide.Model;
            title.appendChild(titleSpan);

            count += 1;
        })

        /*
         * Create Lightbox for Large Image Display
         */
        const lightbox = document.createElement('div')
        lightbox.classList.add('lightbox');

        document.body.appendChild(lightbox);
        const images = document.querySelectorAll('img')
        console.log('images', images);

        images.forEach(image => {
            /* Add Event Listener to Images and setting css class to active */
            image.addEventListener('click', () => {
                lightbox.classList.add('active');
                document.querySelector('.content').style.display = 'none';
                //document.querySelector('.pagination').style.display = 'none';

                /*
                 * Create Image portion of LightBox
                 */
                let galleryImage = document.createElement('img');
                galleryImage.classList.add('galleryImage');
                galleryImage.width = 800;
                galleryImage.height = 534;
                galleryImage.src = image.src // image path
                //console.log(image.src);

                /*
                 * Create EXIF portion of LightBox
                 */
                let galleryExif = document.createElement('p');
                galleryExif.classList.add('galleryExif');
                galleryExif.textContent = image.getAttribute('data-exif');

                /*
                 * Create Text portion of Lightbox
                 */
                let nextSibling = image.nextElementSibling; // Grab the next sibling:
                let galleryText = document.createElement('p');
                galleryText.classList.add('galleryText');
                //console.log(nextSibling.textContent);
                //galleryText.textContent = nextSibling.textContent;


                /* Remove Image For Screen (cleanup) */
                while (lightbox.firstChild) {
                    lightbox.removeChild(lightbox.firstChild)
                }

                /* Add Image to Screen */
                lightbox.appendChild(galleryImage);

                /* Add EXIF to Screen */
                lightbox.appendChild(galleryExif);

                /* Add Content to Screen */
                //lightbox.appendChild(galleryText);


            })

        })

        lightbox.addEventListener('click', () => {
            if (lightbox.hasChildNodes()) {
                lightbox.classList.remove('active'); // Exit Lightbox by removing active css class
                lightbox.classList.add('lightbox');
                document.querySelector('.content').style.display = 'grid';
                //document.querySelector('.pagination').style.display = 'flex';
            }
        })
    };

    const categoryUIError = (error) => {
        console.log("Database Table did not load", error);
    }

    const paginationUISuccess = (parsedData) => {
        console.log('parseData', parsedData);
        pages = [{}];

        database_data.total_count = parsedData.total_count;
        database_data.offset = parsedData.offset;
        total_pages = Math.ceil(database_data.total_count/database_data.per_page);

        console.log('Total Pages =', total_pages);
        for (let x = 0; x < total_pages; x++) {
            //pages[x].page = x+1;
            pages[x] = {page: x+1};
        }
        pages.forEach(link_page => {
            console.log('page', link_page);
            console.log('link', link_page.page);

        })

        createRequest('galleryImagesGet.php', categoryUISuccess, categoryUIError);

    };

    const paginationUIError = (error) => {
        console.log("Database Table did not load", error);
    }
    /* create FETCH request */
    const createRequest = (url, succeed, fail) => {

        //console.log(category.value);
        //console.log('database_data', database_data);
        fetch(url, {
            method: 'POST', // or 'PUT'
            body: JSON.stringify(database_data)
        })
            .then((response) => handleErrors(response))
            //.then(res => res.text())          // convert to plain text
            //.then(text => console.log(text))
            .then((data) => succeed(data))
            .catch((error) => fail(error));
    };

    category.addEventListener('change', () => {
        database_data.category = category.value;
        createRequest('galleryPagination.php', paginationUISuccess, paginationUIError);

    }, false);

   createRequest('galleryPagination.php', paginationUISuccess, paginationUIError);


})();

I like using post instead of get as I don't have to deal with pretty url's as I personally find them a pain. Now all I have to do is finish the links.

Thanks again for the help

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.