0

I have a section on the site where used items parsing from Steam API. Every item has an attribute market_hash_name, classid, and i have virtual items on the site that don’t have these attributes, that have items from Steam.

The problem is this: items from the Steam service are displayed normally, and virtual items are not displayed, an error appears in the site console VM13384:1 Uncaught SyntaxError: Unexpected token u in JSON at position 0, these json requests have the variables + info.classid + and + info.name +, which my virtual items don't have and therefore are not displayed and I get an error. How i can fix this error?

My JS code:

    html_items = '';
    json1.forEach(function(info){
        html_items += '<li class="fast-game-trade-item" style="transform: translate3d(0px, 0px, 0px); background-image: url(https://steamcommunity-a.akamaihd.net/economy/image/' + info.classid + '/23fx23f);"><div class="item_info darkBlueBg">\
            <div class="item_info_img_wrap">\
                <div class="item_info_img">\
                    <img src="https://steamcommunity-a.akamaihd.net/economy/image/' + info.classid + '/110fx100f" alt="' + info.market_hash_name + '">\
                </div>\
            </div>\
            <div class="item_info_description">\
                <div class="item_info_name">' + info.market_hash_name + '</div>\
                <div class="item_info_price">' + info.price + '₽</div>\
            </div>\
            <div class="item_owner">\
                <div class="item_owner_img">\
                    <img src="' + data1.user.avatar + '">\
                </div>\
            </div>\
        </div></li>';
    });
    $('#game_'+data1.game_id+' #block_items_1').html(html_items);

In site templates I solve this problem as follows:

@if(!isset($i->img))
here code for Steam items
@else
here code for virtual items
@endif

How can I use @if @else in my case in Javascript?

EDIT add code with JSON parse:

data1 = JSON.parse(data);
    var string = JSON.stringify(data1.items);
    var json = JSON.parse(string);
    var json1 = JSON.parse(json);
     $('#bank').text(data1.gamePrice);
    if (data1.number == 1) {
        if(window.location.pathname == '/fastgame') {
            $('title').text(Math.round(data.gamePrice,2) + '');
        }
        $('#game_'+data1.game_id+' #chance_1').toggleClass('chance_'+data1.user.id);
        $('#game_'+data1.game_id+' #block_1 .player.first-player').css('background-image', 'url(' + data1.user.avatar + ')');
        $('#game_'+data1.game_id+' #block_1').removeClass('empty');
        $('#game_'+data1.game_id+' #block_1 .players-roulette-container').attr('id','bet_1_'+ data1.betId);
        html_items = '';
        json1.forEach(function(info){
            html_items += '<li class="fast-game-trade-item" style="transform: translate3d(0px, 0px, 0px); background-image: url(https://steamcommunity-a.akamaihd.net/economy/image/' + info.classid + '/23fx23f);"><div class="item_info darkBlueBg">\
                <div class="item_info_img_wrap">\
                    <div class="item_info_img">\
                        <img src="https://steamcommunity-a.akamaihd.net/economy/image/' + info.classid + '/110fx100f" alt="' + info.market_hash_name + '">\
                    </div>\
                </div>\
                <div class="item_info_description">\
                    <div class="item_info_name">' + info.market_hash_name + '</div>\
                    <div class="item_info_price">' + info.price + '₽</div>\
                </div>\
                <div class="item_owner">\
                    <div class="item_owner_img">\
                        <img src="' + data1.user.avatar + '">\
                    </div>\
                </div>\
            </div></li>';
        });
        $('#game_'+data1.game_id+' #block_items_1').html(html_items);
        $('#game_'+data1.game_id+' #price_1').text(data1.price).countTo({
            from: 0,
            to: data1.price,
            speed: 600,
            formatter: function(value, options) {
                return value.toFixed(2);
            }
        });
    }

1 Answer 1

1

Solution to issue "JSON parsing error"

The reason you are getting Uncaught SyntaxError: Unexpected token u in JSON at position 0 is that you are somewhere stuffing undefined into JSON.parse. This is because JSON.parse will convert whatever you passed into it to a string and attempt to parse it, but undefined is not valid JSON, and you are getting an error at the first character already, which is u.

I don't see JSON.parse in your code, so this error must happen in a place you did not copy here.

Everything I'm going to explain below is not going to work unless you fix this error first. So please check where you are parsing your JSON and don't attempt to parse it if the text you are parsing is undefined.

A tip on the side: Open your browser console before the error happens (or refresh the page if you opened it too late). Then you will get more useful error output and most importantly also better info about where the error happened, especially when you have source maps. Even better, you will usually break into the code at the moment the error happens, so you can inspect the variables and see for example why you had undefined there. Also, when you click that file and line number at the right (VM13384:1 in your case), it will show you the line of code where it happened. If the code is minified (which I assume since here it shows line 1), you can click the {} button to auto-format it.


Answer to question "how to embed conditionals in a string"

You can use the ternary conditional operator ?:.

The syntax is condition ? valueIfTrue : valueIfFalse, and it evaluates to valueIfTrue when condition was truthy, otherwise it evaluates to valueIfFalse.

For example:

console.log('Is one greater than two? ' + (1 > 2 ? 'Yes' : 'No') + '!')
// Output: Is one greater than two? No!

Further notes

On a side note, the code will become much neater by using template strings (they use `backticks` and you can embed ${values} in them, and they can contain newlines):

html_items += `
    <li class="fast-game-trade-item" style="transform: translate3d(0px, 0px, 0px); background-image: url(https://steamcommunity-a.akamaihd.net/economy/image/${info.classId}/23fx23f);"><div class="item_info darkBlueBg">
        <div class="item_info_img_wrap">
            <div class="item_info_img">
                <img src="https://steamcommunity-a.akamaihd.net/economy/image/${info.classId}/110fx100f" alt="' + info.market_hash_name + '">
            </div>
        </div>
        <div class="item_info_description">
            <div class="item_info_name">${info.market_hash_name}</div>
            <div class="item_info_price">${info.price}₽</div>
        </div>
        <div class="item_owner">
            <div class="item_owner_img">
                <img src="${data1.user.avatar}">
            </div>
        </div>
    </li>
`;

Of course you could nest them, together with conditionals:

`
    <div class="list">
        ${items.length > 0 ? `
            <ul>
                ${items.map(item => `
                    <li>${item}</li>
                `).join('')}
            </ul>
        `, `
            <strong>No items!</strong>
        `}
    </div>
`

However, with all of this, there is still one issue: You are not escaping your text as HTML entities, so that HTML can sneak in, which can break formatting at best or cause XSS attack vulnerabilities at worst.

You should wrap all the text values in an escaping function. Unfortunately, browsers still don't have a straight-forward function to do that, but it's easy to create one yourself:

function esc (s) {
    const i = document.createElement('i')
    i.innerText = s
    return i.innerHTML
}

This way, you can escape your text values like so:

`
    <div class="item_info_name">${esc(info.market_hash_name)}</div>
`
Sign up to request clarification or add additional context in comments.

3 Comments

great answer, studying it! if you interested, i edit post and add code with JSON.parse
Are you sure that you have triple-encoded JSON? That doesn't sound logical to me. I see you are parsing three times... Maybe show the raw source data as well
Hm OK you are stringifying again once, so it's "only" 2 times in total, but that still sounds weird, plus, the extra stringify+parse is definitely superfluous

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.