can't find error in my code? - javascript

I am making a simple search code. I can't find error. The error message says Uncaught SyntaxError: Unexpected identifier on javascript line 40 (target=document.getElementById("outputPlace").
Do not look at the button, I have not added event listener to it yet.
I just want that when I press enter products are displayed.
HTML CODE
<html>
<head>
<title>Price List </title>
</head>
<body>
<h1> PRICELIST </h1>
<form id="formSearch">
<div>
<label for="searchBox"> Search products here: </label>
<input type="text" placeholder="Type text here to search product" id="searchBox">
</div>
<div id="buttons">
<button id="getAll"> GET ALL PRODUCTS</button>
</div>
</form>
<div id="outputPlace">
</div>
<script src="product.js"></script>
</body>
</html>
JAVASCRIPT CODE
(function(){ //start anonymous function
var list= {
"listOfProducts": [
{
"name":"hard disk",
"price": "50$",
"quality":"good",
},
{
"name":"monitor",
"price":"100$",
"quality": "very good",
},
{
"name":"speakers",
"price":"20$",
"quality": "not bad",
},
{
"name":"headphones",
"price":"12$",
"quality":"bad",
},
{
"name": "mobile phone",
"price": "300$",
"quality": "excellent",
},
{
"name": "usb memory",
"price": "30$",
"quality": "the best",
}
]
},
var target=document.getElementById("outputPlace"),
searchForm=document.getElementById("formSearch"),
productList=list.listOfProducts,
listLength=productList.length,
searchValue=document.getElementById("searchBox"),
searchInput=searchValue.value;
var listMethods = {
searchList: function(event) {
event.preventDefault();
var i;
target.innerHTML="";
if(listLength>0 && searchInput!=="") {
for(i=0;i<listLength;i++) {
var product=productList[i],
whatIsFound=product.name.indexOf(searchInput);
if(whatIsFound!==-1){
target.innerHTML+='<p>'+product.name+', '+product.price+', '+product.quality+'click here to buy</p>'
}
}
}
},
};
searchForm.addEventListener("submit",listMethods.searchList,false);
}) (); //end anonymous function

You have a comma after that large JSON object you defined at the top of your JavaScript, followed by another var.
var list= {
"listOfProducts": [
{
"name":"hard disk",
"price": "50$",
"quality":"good",
},
...[a bunch of stuff]...
},
var target=document.getElementById("outputPlace"),
searchForm=document.getElementById("formSearch"),
productList=list.listOfProducts,
listLength=productList.length,
searchValue=document.getElementById("searchBox"),
searchInput=searchValue.value;
Both of the two other proposed answers would fix this (well ok Otome deleted their answer which was to drop the second var).

Change this
var list = {
...
},
var target=document.getElementById("outputPlace"),
to this:
var list = {
...
};
var target=document.getElementById("outputPlace"),

And you have one more comma at the end of script, after }

Related

getting a specific value from JSON.parse() javascript

Hello I am trying to figure out how to get the "changes" value from
{ data: { sequenceStart: 1613141716565, symbol: 'KCS-BTC', changes: { asks: [Array], bids: [] }, sequenceEnd: 1613141716565 }, subject: 'trade.l2update', topic: '/market/level2:KCS-BTC', type: 'message' }
The data is stored in let data = JSON.parse(msg)
I have tried console.log(data.data.changes) but get undefined, im lost because console.log(data.data) seems to get me part way there but not when I add .changes?
Can you check my code below.
I think your msg is not formated correctly , you can compare with my code
<body >
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($){
var msg = '{"data": { "sequenceStart": "1613141716565", "symbol": "KCS-BTC", "changes": { "asks":[["0","0","1613141798456"]],"bids":[]}, "sequenceEnd": 1613141716565 }, "subject": "trade.l2update", "topic": "/market/level2:KCS-BTC", "type": "message" }';
var data = JSON.parse(msg);
console.log(data.data.changes);
var msg1 = '{"sequenceStart":1613141798456,"symbol":"KCS-BTC","changes":{"asks":[["0","0","1613141798456"]],"bids":[]},"sequenceEnd":1613141798456}';
var data1 = JSON.parse(msg1);
console.log(data1.changes);
});
</script>
</body>

Replace jQuery with vanilla JS when parsing JSON, and other improvements

I would like get rid of jQuery for this simple task, but I don't know how to use vanilla JS to do the job. The page works fine, but I recognize that it is a mess, and I would like to improve the invisible, under the hood code.
I am a complete noob, I will try to explain what I've done but I need your help to simplify as much as possible and clean the code (one function only / alternative to javascript in "href" / everything else that comes to mind). And to get rid of a 88kB .js file just to call a function.
The web page contains two links that point to local Icecast streams.
When one selects a stream by clicking a link,
the common audio player loads the corresponing source URL (function changeStream());
the link is highligted and every other link returns to the default CSS (function changeBg());
the variable number is set to the correspondibg element number to allow title parsing;
the jQuery function getTitle() is executed.
Additional notes:
HTML IDs with "*-js" means that they are modified by a javascript function;
I may have mispelled something below, I have rewritten variables and other parts with easier to understand names;
Getting rid of jQuery is my priority, but other improvements are well accepted.
Thank you in advance
The webpage contains is
<!doctype html>
<html lang="en">
<head>[...]</head>
<body>
<div class="links">
<a id="/sourceA-js" class="sourceLink"
href="javascript:changeStream('/radio/sourceA'); changeBg('/sourceA-js'); var number=0; getTitle();">
<span class="sourceText">Stream A</span></a>
<a id="/sourceB-js" class="sourceLink"
href="javascript:changeStream('/radio/sourceB'); changeBg('/sourceB-js'); var number=1; getTitle();">
<span class="sourceText">Stream B</span></a>
</div>
<div id="currentTrackInfo">
<p>Track: <span id="currentTrackTitle-js">Please select a radio stream</span>
</p>
<audio id="radio-js" class="radioPlayer" controls>
<source src="" type="audio/mpeg">
</audio>
</div>
<script>
function changeBg (streamId) {
var boxes = document.getElementsByClassName('sourceLink'),
i = boxes.length;
while (i--) {
boxes[i].removeAttribute('style');
}
document.getElementById(streamid).setAttribute('style', 'color:grey;background-color:red;');
}
function changeStream (stream) {
document.getElementById('radio-js').pause();
document.getElementById('radio-js').setAttribute('src', stream);
document.getElementById('radio-js').load();
document.getElementById('radio-js').play();
}
</script>
<script src="/static/js/jquery.js"></script>
<script>
function getTitle () {
jQuery.get('status-json.xsl', {}, function (response) {
$('#currentTrackTitle-js').html(response.icestats.source[number]['title']);
document.title = response.icestats.source[number]['title'];
});
}
gettitle();
setInterval(gettitle, 15000);
</script>
</body>
</html>
The parsed file, status-json.xsl, contains
{
"icestats": {
"admin": "mail",
"host": "domain",
"location": "name",
"server_id": "version",
"server_start": "humandate",
"server_start_iso8601": "computerdate",
"source": [
{
"audio_info": "bitrate=320",
"bitrate": 320,
"genre": "Jazz",
"listener_peak": 2,
"listeners": 1,
"listenurl": "address",
"server_description": "streamdescription",
"server_name": "streamname",
"server_type": "audio/mpeg",
"server_url": "/radio/jazz",
"stream_start": "humandate",
"stream_start_iso8601": "computerdate",
"title": "author - title",
"dummy": null
},
{
"audio_info": "bitrate=320",
"bitrate": 320,
"genre": "Jazz",
"listener_peak": 2,
"listeners": 1,
"listenurl": "address",
"server_description": "streamdescription",
"server_name": "streamname",
"server_type": "audio/mpeg",
"server_url": "/radio/jazz",
"stream_start": "humandate",
"stream_start_iso8601": "computerdate",
"title": "author - title",
"dummy": null
}
]
}
}
This appears to be the only jQuery code that you want to replace:
jQuery.get("status-json.xsl", {}, function(response) {
$('#currentTrackTitle-js').html(response.icestats.source[number]['title']);
document.title = response.icestats.source[number]['title'];
});
Vanilla JavaScript equivalent to jQuery.get() is fetch. This will read JSON string from file and convert it to a JavaScript object:
fetch("status-json.xsl")
.then(response => {
// parse JSON from 'status-json.xsl' file
return response.json();
})
.then(status => {
// perform your app logic here
});
This jQuery code:
$('#currentTrackTitle-js').html(response.icestats.source[number]['title']);
can be replaced with this vanilla JavaScript:
const currTitle = document.getElementById('currentTrackTitle-js');
currTitle.innerHTML = status[number]['title'];
Putting it all together:
const currTitle = document.getElementById('currentTrackTitle-js');
fetch("status-json.xsl")
.then(response => {
return response.json();
})
.then(status => {
currTitle.innerHTML = status.icestats.source[number]['title'];
document.title = status.icestats.source[number]['title'];
});

jQuery get data from JSON file dynamically

I am trying to make a simple multilanguage site!
I have 3 buttons for 3 languages, when I press one of them, I get the value of that button value with jQuery and store it in a variable named clicked and I want to get data from JSON like this: data.clicked.name
How can i get the value of clicked on data.clicked.name?
html file
<div id="container">
<input class="btnL" type="button" value="MK">
<input class="btnL" type="button" value="EN">
<input class="btnL" type="button" value="AL">
</div>
script
<script type="text/javascript">
$(document).ready(function () {
$(".btnL").click(function () {
var clicked = $(this).attr("value");
$.getJSON('language.json', function (data) {
console.log(data.clicked.name);
// ex. if the value of clicked variable is="EN"
// I want to get this console.log(data.EN.name)
});
});
});
</script>
language.json
{
"EN": {
"name": "Name",
"surname": "Surname"
},
"AL": {
"name": "Emri",
"surname": "Mbiemri"
},
"MK": {
"name": "Име",
"surname": "Презиме"
}
}
Use brackets
console.log(data[clicked].name);

Angularjs adding dynamically form fields in various forms

Using ng-repeat I am creating bunch of forms with values in it. With each form there is also button to add rows to that particular form with new fields. Code is below
HTML:
<form name="{{form.name}}"
ng-repeat="form in forms">
<h2>{{form.name}}</h2>
<div ng-repeat="cont in form.contacts">
<input type="text" class="xdTextBox" ng-model="cont.ac"/>
<input type="text" class="xdTextBox" ng-model="cont.a_number"/>
<input type="text" class="xdTextBox" ng-model="cont.p_id"/>
</div>
<button ng-click="submit(form)">Submit</button>
<button ng-click="addFields(form)">Add</button>
<hr>
</form>
Javascript:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.forms = [{
"name" : "form1", "ac": 251, "a_number": "7933", "p_id": 33
}, {
"name": "form2", "ac": 252, "a_number": "7933", "p_id": 4
}, {
"name": "form3", "ac": 253, "a_number": "7362", "p_id": 3
}];
$scope.addFields = function (form) {
form.contacts.push({name:'', ac: '', a_number: '', p_id: '' });
}
$scope.submit = function(form){
console.log(form.contacts);
}
});
It is not working. Here is the plunker for it:
http://plnkr.co/edit/THdtLgkwKrV7imqZGjL2?p=preview
This is how it should be looking(Difference is data object received from db is little different than this previously asked question):
http://plnkr.co/edit/fETiSYVW7Y5C1yTCwizd?p=preview
Please let me know where the problem is. Thanks
Your addFields method is the problem. Just add a case for when form.contacts is undefined and set it to empty array. Or make each form item start with a contacts key set to an empty array.
$scope.addFields = function (form) {
if(typeof form.contacts === 'undefined') {
form.contacts = [];
}
form.contacts.push({name:'', ac: '', a_number: '', p_id: '' });
}
Works with that change in this fork of your plunk.
Angular also has a helper function for determining when something is undefined you might want to use though I do not know if it really makes any difference.
angular.isUndefined(form.contacts)

Big nested JSON data and updating DOM when changed

I'm dealing with pretty big amounts of json and the data is something like this:
{
"name": "John Smith",
"age": 32,
"employed": true,
"address": {
"street": "701 First Ave.",
"city": "Sunnyvale, CA 95125",
"country": "United States"
},
"children": [
{
"name": "Richard",
"age": 7,
"field": {
"field": "value"
}
}
]
}
Whenever I change anything I get a new response which is somewhat similar to the previous data, but where new properties might have been added, stuff might have been removed and so on.
My testcode is something like this (don't mind the infinite amount of bad practices here):
<div data-viewmodel="whatevz">
<span data-bind="text: stuff['nested-thingy']"></span>
</div>
<script>
function vm() {
var self = this;
this.stuff = ko.observable();
require(["shop/app"], function (shop) {
setTimeout(function () {
self.stuff(shop.stuff);
}, 1200);
});
}
ko.applyBindings(new vm(), $("[data-viewmodel]")[0]);
</script>
I want stuff['nested-thingy'] to be updated whenever stuff is updated. How do I do this without all kinds of mapping and making everything observable?
You should only have to update your biding:
<div data-viewmodel="whatevz">
<span data-bind="text: stuff()['nested-thingy']"></span>
</div>
You have to access the value of the observable with the (). That returns your object and then you can access it. The content of the binding is still dependent on the observable stuff therefore it should update whenever stuff is updated.
At least my fiddle is working that way: http://jsfiddle.net/delixfe/guM4X/
<div data-bind="if: stuff()">
<span data-bind="text: stuff()['nested-thingy']"></span>
</div>
<button data-bind="click: add1">1</button>
<button data-bind="click: add2">2</button>
Note the data-bind="if: stuff(). That is necessary if your stuff's content is empty at binding time or later...
function Vm() {
var self = this;
self.stuff = ko.observable();
self.add1 = function () {
self.stuff({'nested-thingy': "1"});
};
self.add2 = function () {
self.stuff({'nested-thingy': "2"});
};
}
ko.applyBindings(new Vm());
Any reason you can't use the mapping plugin to deal with the mapping for you? You can use the copy option for the properties that you don't want to be made observables:
var mapping = {
'copy': ["propertyToCopy"]
}
var viewModel = ko.mapping.fromJS(data, mapping);

Categories