json_encode() Data Being Automatically Converted Into A Javascript Object Without JSON.parse() Being Used

Issue

I have some PHP and JavaScript that works by PHP updating a MySQL database, and then outputting the updated code back onto the page without a hard refresh using the JavaScript fetch() method. This code works, but there is a part I don’t understand — why is it when the json_encode() PHP method is used, which converts the data to a JSON string, when it is then used in the JavaScript it is automatically being converted into a JavaScript object without JSON.parse() being used?

In the Javascript when I use JSON.parse() it understandly throws an error, because the data isn’t a string (which initially caused some confusion), when I console log the json variable being used in the JavaScript it does indeed return a JavaScript object where I can access its properties and methods etc.

There is no other JSON or json_encode() being used on the page (or indeed the site).

Also in the PHP script it echoes the JSON with echo json_encode($board_row); when the data is fetched from the database, before any HTML content is outputted. When I try and echo this in the HTML to see the value of json_encode($board_row); it just outputs the word false. I don’t understand what is going on there either?

If I manually add a simply array into the HTML such as $arr = array('a' => 1, 'b' => "hello", 'c' => null); and then echo that in the HTML with echo json_encode($arr); as excepted it outputs a JSON string.

If someone could kindly explain why this is happening, that would be wonderful.

PHP

if (isset($_POST['submit-board-name'])) {

    $create_board_name = $_POST['create-board-name'];
    
    try {
        // insert into database
        $createBoardSQL = "
            INSERT INTO boards (board_name, user_id) 
            VALUES (:board_name, :user_id )
        ";
    
        $bstmt = $connection->prepare($createBoardSQL);
        $bstmt->execute([
            ':board_name' => $create_board_name,
            ':user_id' => $db_id
        ]);

        // ----- fetch as JSON
        if(isset($_POST['json_response'])) {
            $board_stmt = $connection->prepare("
                SELECT * FROM `boards` WHERE `user_id` = :user_id 
                AND `board_name` = :board_name 
                ORDER BY `board_id` DESC");

            $board_stmt -> execute([
                ':user_id' => $db_id,
                ':board_name' => $create_board_name
            ]); 

            $board_row = $board_stmt->fetch();

            header('Content-type: application/json');
            echo json_encode($board_row);
            exit;
        }

    } catch(PDOException $e) {
        echo "Error: " . $e->getMessage();
    }
}

JavaScript

let boardModuleForm = document.querySelector('.board-module-form');

// URL details
let myURL = new URL(window.location.href),
pagePath = myURL.pathname;

if (boardModuleForm) {
    boardModuleForm.addEventListener('submit', function (e) {
    if (e.submitter && e.submitter.classList.contains('js-fetch-button')) {
            e.preventDefault();

            var formData = new FormData(this);

            formData.set(e.submitter.name, e.submitter.value);
            formData.set('json_response', 'yes');

            fetch (pagePath, {
                method: 'post',
                body: formData
            })
            .then(function(response) {

                if (response.status === 200) {
                    response.json().then(function(json){
                        
                        const newBoardName = json.board_name,
                        boardId = json.board_id;
                            
                        const newButton = `
                        <button name="board-name" type="submit">
                            <span>${newBoardName}</span>
                            <span style="margin:0" class="add-icon flex">+</span>
                        </button>
                        <input class="board-id-value" type="hidden" value="${boardId}">
                        `
                        // add new button from above onto page
                        document.querySelector('.board-list').insertAdjacentHTML('afterbegin', newButton);
                    
                    });

                }

            })
            .catch(function(error) {
                console.error(error);
            })

        }

    })
}

Solution

In the handler for your fetch response, you call response.json().then(...). This is already doing the JSON parsing for you without needing to call JSON.parse manually.

Answered By – Moshe Katz

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published