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);
}
});
}
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>
`
Related
Array used in repeat for loop
let loopArr = ["item.name + ' /'+ item.DisplayName? item.DisplayName: item.otherDisplayName",
"item.description + ' /'+ item.anotherDescription"]
Template
<div repeat.for = item of data">
<div repeat.for = "row of loopArr">
<span textcontent.bind="renderRow(row, item)></span>
</div>
</div>
Component method
renderRow(row, item){
return eval(row)
}
Actually I wanted to display like below in template
<div repeat.for = item of data">
<div repeat.for = "row of loopArr">
<span>${item.name + ' /'+ item.DisplayName? item.DisplayName: item.otherDisplayName} </span>
<span>${item.description + ' /'+ item.anotherDescription} </span>
</div>
</div>
Since I wanted to loop through dynamic loopArr, instead of using eval to convert from string to value, is there any better way to compute the value from string? Also, eval doesnt work for multiline statements, is there any other approach/way to handle the above problem?
How to convert string to value and display in aurelia template?
Any help would be appreciated!
I'm not sure why you're adding the logic in string format and using eval. You could directly add it to the template and display it:
<div repeat.for="item of data">
<span>${item.name + '/' + (item.DisplayName ? item.DisplayName: item.otherDisplayName)}</span>
<span>${item.description + ' / '+ item.anotherDescription} </span>
</div>
Let's assume you have a list of custom string formats and you are importing them from another file. You could create an array of functions instead of array of strings. This is much better way of deferring the string creation than running eval
displayTemplates = [
item => item.name + '/' + (item.DisplayName ? item.DisplayName: item.otherDisplayName),
item => item.description + '/'+ item.anotherDescription
]
and then in the template:
<div repeat.for="item of data">
<template repeat.for="func of displayTemplates">
<span>${ func(item) }</span> <!-- call each func on item object -->
</template>
</div>
Also, there is a logical error in your string format. + operator has higher precedence compared to the ternary operator.
So,
item.name + '/' + item.DisplayName ? item.DisplayName : item.otherDisplayName
is actually evaluated as
(item.name + '/' + item.DisplayName) ? item.DisplayName : item.otherDisplayName
So, this expression will always evaluate to item.DisplayName because item.name + '/' + item.DisplayName will never be falsy.
You need to add () around the ternary operation:
item.name + '/' + (item.DisplayName ? item.DisplayName: item.otherDisplayName)
// OR
item.name + '/' + (item.DisplayName ?? item.otherDisplayName)
I use this error code when this information is not found while I echo the JS variable, but it doesn't work in PHP function
$(document).click(function() {
$('#more').empty();
$('#detail-more').empty();
$.get('/inbox', function(date) {
$.each(date, function(app, subcatObj) {
var time = timeAgo(subcatObj.created_at);
if (subcatObj.id == id) {
var id =subcatObj.id;
$('#detail-more').html(`<div class="peers peer-greed">` +
`<div class="peer mR-20"><img class="bdrs-50p w-3r h-3r" alt="" src="https://randomuser.me/api/portraits/men/11.jpg"></div>` +
`<div class="peer"><small>${time}</small>` +
`<h5 class="c-grey-900 mB-5"></h5><span>Then:<?php app\User::find(${id})->name; ?> </span></div>` +
`</div>` +
`<div class="peer"><i class="fa fa-reply"></i></div>`);
$('#more').html(`<h4> ${subcatObj.title} </h4><p> ${subcatObj.text}</p>`);
}
});
});
});
error:"Use of undefined constant id - assumed 'id' (this will throw an
Error in a future version of PHP) (View:
C:\xampp\htdocs\tasvirevarzesh\resources\views\dashboard\email\index.blade.php)"
if you write in others js files you should use input type="hidden"
in blade to get value and then handle it.
You can use
in blade and use {{ }} to coding something here
I am trying to generate a dynamic link to a movie poster using an Axios call.
function getMovies(searchText){
axios.get('https://api.themoviedb.org/3/search/movie?api_key='+ API_KEY + "&language=en-US&query=" + searchText + "&page=1&include_adult=false")
.then((response) => {
let movies = response.data.results;
let output = '';
$.each(movies, (index, movie) => {
console.log("http://image.tmdb.org/t/p/w185/" + movie.poster_path);
let movieUrl = "http://image.tmdb.org/t/p/w185/" + movie.poster_path;
output += `
<div class="col-md-3">
<div class="well text-center>
<img src="${movieUrl}" >
<h5>${movie.title}</h5>
<a onclick="movieSelected('${movie.imdbID}') target="_blank" class="btn btn-primary" href="#">Movie Details</a>
</div>
</div>
`;
});
$('#movies').html(output);
})
.catch((err) => {
console.log(err);
});
};
The console.log outputs the correct link syntax, for example: http://image.tmdb.org/t/p/w185//8WmT9i9sili2uLNzGGm3nc7AUR3.jpg
but on the DOM the link is formatted with spaces instead of / for example:
<img src=" http:="" image.tmdb.org="" t="" p="" w185="" 8wmt9i9sili2ulnzggm3nc7aur3.jpg"="">
What is going on here?
Do I need to use something like paramsSerializer or encodeURI or is it something else?
The class attribute value for the div below wasn't closed with a double quote.
<div class="well text-center>
The browser could only try to make sense of it and it treats every character until the next " in img src=" as a value of the class attribute for the div.
Then, the value of movieUrl is treated as attribute values as well not without it properly escaped.
Closing the missing quotes (<div class="well text-center">) should resolve that issue.
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 4 years ago.
I have been assigned to update a classic asp website with a Prestashop template called Autotune Responsive Prestashop Theme. My client wants all the ajax bells and whistles they see online in Template Monster. Template Monster made static html files for my client from this template which includes all the custom Prestashop javascript libraries. So far I am unable to use these custom Prestashop jquery/ajax libaries as they were intended so I have to write my own code to paginate, add to cart, show item popup, etc. Everything works great except for appending html. For example, pagination. When I view a list of parts in grid view and I click to append nine more parts, the html gets appended OK but onclick events to the Add To Cart button and "eye" icon popup are dead for the new items that were appended. Mouse over events are OK. Same issue when I append html to the cart popup - I see the added cart items in the cart popup but the "x" (delete) won't work when clicked although the color changes when moused over. It's as if I need to update something after appending. I'm stumped. Here is the pagination code:
$(function() {
$('#infiniteScrollMore').click(function(){
var numItems = parseInt($('#NumItems').text());
var pageNbr = parseInt($('#PageNbr').text()) + 1;
$('#PageNbr').text(pageNbr);
$.get('AppendParts.asp?PageNbr=' + pageNbr + '&NumItems=' + numItems,function (data) {
$('.product_list').append(data);
numNextItems = parseInt(numItems) - (parseInt(pageNbr) * 9);
if (parseInt(numNextItems) >= 9) numNextItems = 9;
setTimeout(function(){$('#NumNextItems').text(' (' + numNextItems + ')')},2000);
if ((parseInt(pageNbr) * 9) >= parseInt(numItems))
{
$('#infiniteScrollMore').hide();
setTimeout(function(){$('#NewSearchButton').show();},2000);
}
});
});
});
I am just using .append to append html to the product_list ul. AppendParts.asp writes the html, which is...
<li class="ajax_block_product">
<div class="product-container" itemscope itemtype="https://schema.org/Product">
<div class="left-block">
<div class="product-image-container">
<div class="tmproductlistgallery rollover">
<div class="tmproductlistgallery-images opacity">
<a class="product_img_link cover-image" href="product.asp?PartNbr=<%=pageCache("PartNbr")%>&StockNbr=<%=pageCache("StockNbr")%>&ProductCode=<%=pageCache("ProductCode")%>&MachineType=<%=pageCache("MachineType")%>&Model=<%=pageCache("Model")%>&Category=<%=pageCache("Category")%>&SubCategory=<%=pageCache("SubCategory")%>" title="<%=pageCache("Description") & " " & pageCache("Make") & " " & pageCache("PartNbr") & " " & pageCache("Class")%>" itemprop="url">
<img class="img-responsive" src="http://<%=theImage%>" alt="" title="<%=pageCache("Description") & " " & pageCache("Make") & " " & pageCache("PartNbr") & " " & pageCache("Class")%>">
</a>
<a class="product_img_link rollover-hover" href="product.asp?PartNbr=<%=pageCache("PartNbr")%>&StockNbr=<%=pageCache("StockNbr")%>&ProductCode=<%=pageCache("ProductCode")%>&MachineType=<%=pageCache("MachineType")%>&Model=<%=pageCache("Model")&Category=<%=pageCache("Category")%>&SubCategory=<%=pageCache("SubCategory")" title="<%=pageCache("Description") & " " & pageCache("Make") & " " & pageCache("PartNbr") & " " & pageCache("Class")%>" itemprop="url">
<img class="img-responsive" src="http://<%=theImage%>" alt="" title="<%=pageCache("Description") & " " & pageCache("Make") & " " & pageCache("PartNbr") & " " & pageCache("Class")%>">
</a>
</div>
</div>
<div class="functional-buttons">
<div class="qv-wrap">
<a class="quick-view" data-id="<%=pageCache("ProductCode") & ":" & pageCache("StockNbr") & ":" & pageCache("PartNbr")%>" href="#" onclick="return false;" data-fancybox-type="ajax" data-type="ajax" data-href="#" title="Quick View"></a>
</div>
<div class="compare">
<a class="add_to_compare" href="product.asp?PartNbr=<%=pageCache("PartNbr")%>&StockNbr=<%=pageCache("StockNbr")%>&ProductCode=<%=pageCache("ProductCode")%>&MachineType=<%=pageCache("MachineType")%>&Model=<%=pageCache("Model")%>&Category=<%=pageCache("Category")%>&SubCategory=<%=pageCache("SubCategory")%>" data-id-product="<%=pageCache("ProductCode") & ":" & pageCache("StockNbr") & ":" & pageCache("PartNbr")%>" title="Detailed View"></a>
</div>
</div>
... abbreviated a bit. Here is the fancybox code:
$(function() {
$('.quick-view').click(function(){
var idStrArray = $(this).attr('data-id');
var idStr = idStrArray.split(':');
var productCode = idStr[0];
var stockNbr = idStr[1];
var partNbr = idStr[2];
$.fancybox({
'closeClick': true,
'hideOnContentClick': true,
'padding': 0,
'width': 1021,
'autoDimensions': false,
'height': 500,
'type': 'iframe',
'tpl': {wrap: '<div class="fancybox-wrap fancybox-quick-view" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>'},
'href': 'product-popup.asp?PartNbr=' + partNbr + '&ProductCode=' + productCode + '&StockNbr=' + stockNbr,
'beforeClose': function() {}
}
});
});
});
What am I missing?
You have to the event trigger like this -
$( "body" ).on( "click", "p", function() {
alert( $( this ).text() );
});
Use jQuery .on() method. Read the doc
I'm trying to delete and replace "article" tags by new one using as source a json array, but i'm always getting only the last element of the JSON array…
Here how look my html structure:
<main id="main" class="site-main" role="main">
<article >
<header class="entry-header">
TEST 1
test
<div>TAGS:dog</div>
</header>
</article>
<article >
<header class="entry-header">
TEST 2
test
<div>TAGS:cat</div>
</header>
</article>
</main>
and here is my javascript function, using jquery to remove and replace the previous posts with the new ones.
function get_posts($params){
var $container = $('#main');
var $content = $container.find('article');
var $status = $('.ajax_tag');
var counter = 0;
…
Jquery.ajax statement here
…
$.each(data,function(index, post){
//$content.children().remove();
$content.empty();
console.log(index);
//$content.replaceWith('<article>' + post.title + '</article>');
//console.log(data.length);
if ( counter != data.length ) {
console.log('before : ' + counter);
$content.append('<article>' + post.title + '</br>' + '</article>');
counter += 1;
console.log('after : ' + counter);
} else {
return false;
}
});
So from here it's not clear to me how I can perform that operation.
The only way i manage to have the full list of my array was using «.append()» but without «.empty()» which then append the array content to each «article» tags.
PS: i have look at the .each(), $.each(), .map(), $.map(), for and for…in all the example and explanation i found are using the CSS "li" tag which seems to have implicite iteration where the tags «article», «div», «span» doesn't.
Hope i'm clear enough, any input would be much appreciated.
Thanks!
I finally fixed my issue with this solution, basically i'm using the jQuery .remove() method instead of the .empty() one, and the it works perfectly.
$.each(data,function(index, post){
$content.remove();
$content.append('<article>' + post.title + '</br>' + '</article>');
});