Optimize trie implementation to search autocomplete - javascript

I have a project in which let the user to lookup for countries in a json file,
i've changed the structure of my json file from:
{
"AE": {"name": "United arab emirates","alternate": "UAE"},
"GB": {"name": "United kingdom","alternate": "Great Britain England","weight": "2.5"},
"US": {"name": "United states","alternate": "USA United States of America","weight": "3.5"},
.........
}
to this structure:
var countries = {
"name": "United arab emirates","alternate": "UAE",
"name": "United kingdom","alternate": "Great Britain England","weight": "2.5",
"name": "United states","alternate": "USA United States of America","weight": "3.5",
.........
}
but i couldn't figure how to edit the js code right to work with the json new structure,
here is the my code:
countries.js :
(function () {
'use strict';
// var log = console.log.bind(console);
// No timing in IE (sucker)
if(!console.time) {
console.time = console.timeEnd = function() {};
}
var countries, index;
function indexData() {
index = new T.Index({
'name' :'countries',
'indexSubstring': false,
'intersectResults': true
});
console.time('loading');
index.load(function(err) {
if(err) {
console.time('indexing');
Object.keys(countries).forEach(function(id) {
var country = countries[id];
var toIndex = [country.name , country.alternate].join(' ');
index.add(id, toIndex, country.weight || 1);
});
console.timeEnd('indexing');
console.time('saving');
index.save(function() {
console.timeEnd('saving');
});
}
else {
// Already loaded
window.index = index;
console.timeEnd('loading');
}
});
}
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if(request.readyState === 4) {
// Break the cyclic reference
request.onreadystatechange = null;
if (typeof request.responseText === "string") {
try {
countries = JSON.parse(request.responseText);
} catch(e) {
// do something
}
// Index, if data was loaded
if(countries) {
indexData();
}
}
}
};
request.open('get', 'data/countries.json', true);
request.send();
var search = document.getElementById('search');
var results = document.getElementById('results');
var lastVal;
function lookup() {
var query = search.value;
if(lastVal === query) {
return;
}
// Time the lookup
console.time('lookup: ' + query);
var ids = index.search(query);
console.timeEnd('lookup: ' + query);
// render the list
results.innerHTML = ids.map(function(id) {
var country = countries[id];
return '<li rel="' + id + '">' + country.name + '</li>';
}).join('');
lastVal = query;
}
search.addEventListener('keyup', lookup, false);
}).call(null);
countries.html:
<html>
<head>
<title>Trie.js</title>
<link rel="stylesheet" type="text/css" href="style.css">
<!--- trie-structure implementation ---->
<script type="text/javascript" src="https://rawgit.com/wunderlist/trie.js/master/dist/trie.js"></script>
</head>
<body>
<label>Type in a country name</label>
<input id="search" autocomplete="off" autofocus="autofocus" />
<ul id="results" />
<script type="text/javascript" src="js/countries.js"></script>
</body>
</html>
Update:
am also trying to limit the result to 5 suggestions. but i am stuck too.
please help thanks.

I don't understand what do you want to change with your search? It uses triejs library to build a tree structure, based on your json file, and triejs's search method to find the results based on the input. It looks like it works.
To limit the output you could slightly change your map function like this, for example:
results.innerHTML = ids.map(function(id, i) {
var country = countries[id];
if (i < 5) {
return '<li rel="' + id + '">' + country.name + '</li>';
}
}).join('');

Related

LinkedIn Works with LinkedIn's testDevCo not with wanted company page

I have a problem fetching company updates, but my code works fine with the
following Linkedin testDevCo "var cpnyID = 2414183; //LinkedIn's testDevCo
So My question is that I am an admin to the company that I want to fetch
the updates i from, but why do I get the following error ?
{
"errorCode": 0,
"message": "Unknown authentication scheme",
"requestId": "MRJ33C5FVX",
"status": 401,
"timestamp": 1540989274268
}
Code:
<script type="text/javascript" src="https://platform.linkedin.com/in.js">
api_key: 8616po0krrhh2k
onLoad: onLinkedInLoad, onLinkedInAuth
</script>
<div id="displayUpdates"></div>
<script type="text/javascript">
function onLinkedInLoad() {
IN.Event.on(IN, "auth", onLinkedInAuth);
console.log("On auth");
}
function onLinkedInAuth() {
var cpnyID = 86104; //the Company ID for which we want updates
IN.API.Raw("/companies/" + cpnyID + "/updates?event-type=status-update&start=0&count=3&format=json").method("Get").result(displayCompanyUpdates)
console.log("After auth");
}
function displayCompanyUpdates(result) {
var div = document.getElementById("displayUpdates");
var el = "<ul>";
var resValues = result.values;
for (var i in resValues) {
var share = resValues[i].updateContent.companyStatusUpdate.share;
var isContent = share.content;
var isTitled = isContent,
isLinked = isContent,
isDescription = isContent,
isThumbnail = isContent,
isComment = isContent;
if (isTitled) {
var title = isContent.title;
} else {
var title = "News headline";
}
var comment = share.comment;
if (isLinked) {
var link = isContent.shortenedUrl;
} else {
var link = "#";
}
if (isDescription) {
var description = isContent.description;
} else {
var description = "No description";
}
/*
if (isThumbnailz) {
var thumbnailUrl = isContent.thumbnailUrl;
} else {
var thumbnailUrl = "http://placehold.it/60x60";
}
*/
if (share) {
var content = "<a target='_blank' href=" + link + ">" + comment + "</a><br>";
//el += "<li><img src='" + thumbnailUrl + "' alt=''>" + content + "</li>";
el += "<li><div>" + content + "</div></li>";
}
console.log(share);
}
el += "</ul>";
document.getElementById("displayUpdates").innerHTML = el;
}
</script>
Premission:(r_basicprofile, r_emailaddress, rw_company_admin, w_share)
I am an admin, I can see the company under the "MANAGE" section. But I don't
have the company as my current position in my profile.
"check if you are sending the right request" => how do I do it ?
couple of things you can do/check:
show us your code
show us your application permissions
check if you are an administrator of the company page and the application
check if you have the correct companyID
check if you are sending the right request.

Why is this JSON file reading strangly

I have a JSON document here. I have validated it with JSlint.
The JSON is of this format:
[{
"date": "2017-02-10",
" action": "Do a thing",
"state": "closed",
"url": "https:someurl.com"
},
....
I have some HTML here, which exists only to read and output the JSON.
The HTML looks like this:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
</head>
<body>
<script>
deadlines = []
start();
function start() {
var req = new XMLHttpRequest();
req.open("GET", "http://joereddington.com/deadlines.json");
req.overrideMimeType("application/json");
req.send(null);
req.onreadystatechange = function() {
if (req.readyState == 4 && req.status == 200) {
var obj = JSON.parse(req.responseText);
deadlines = obj
for (deadline in deadlines) {
var output = '';
for (var property in deadline) {
console.log(property)
output += property + ': ' + deadline[property] + '; ';
}
console.log(output);
console.log(deadline.date)
console.log(deadline.action)
}
}
};
}
</script>
</body>
However, when I try and list the properties of each object, I get very strange results:
rather than the names and values I'm looking for. Can someone tell me what I'm doing wrong?
$.each(JSON.parse(deadlines), function (index, deadline) {
var output = '';
for (var property in deadline) {
console.log(property)
output += property + ': ' + deadline[property] + '; ';
}
console.log(output);
console.log(deadline.date);
console.log(deadline.action);
});
Your JSON string contains extra space. It should be "action" not " action".
for...in loops over the keys (since it's an array: "0", "1" ...). Use for...of or forEach or a basic for loop.
I recommend forEach like this:
deadlines.forEach(function(deadline) {
// ...
});

Parsing json array to array javascript

I have an array with json data:
var jsonString=[
{
"url": "http://www.anurl.com",
"tags": {
"Event": 6,
"Event1": 2
}
}
]
Now i want to build the next structure:
var data= [ {"text":"Event", "weight" : "6", "link" :"www.anurl.com"} //etc ];
Now i looked into the var array = $.parseJSON(JSON.stringify(jsonString));
and on the result i try to build my data array with .push();
But how can i insert the Event: 6 part? i cannot do array.tags[0] as array.tags will give me both of them.
So how can i solve this problem?
You are using object literals in javascript, the example you provided:
var jsonString=[{
"url": "http://www.anurl.com",
"tags": {
"Event": 6,
"Event1": 2
}
}];
jsonString is an array, and the element tags is an object NOT an array so you can access it like this:
var event = jsonString[0].tags.Event;
You can read the attributes of the tags object like the example below :
function loadArray(urls){
xhrDoc= new XMLHttpRequest();
if (xhrDoc.overrideMimeType)
xhrDoc.overrideMimeType('text/plain; charset=x-user-defined');
xhrDoc.onreadystatechange =function()
{
if (this.readyState == 4)
{
if (this.status == 200)
{
var data= this.response; //Here is a string of the text data
printUrls(data);
}
}
};
xhrDoc.open('GET', urls , true);
xhrDoc.send();
}
function printUrls(response) {
var arr = JSON.parse(response);
var i;
var out = "";
for(i = 0; i < arr.length; i++) {
console.log(arr[i].url);
console.log(arr[i].tags['Event']); // Read Event
console.log(arr[i].tags['Event1']); //// Read Event1
out = "URL : "+ arr[i].url + " Event : "+ arr[i].tags['Event']+ " Event1 : " + arr[i].tags['Event1'] + "\n";
}
document.getElementById("id01").innerHTML = out;
}
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="parseJsonFile.js"></script>
</head>
<body onload="loadArray('parseJson.json')">
<div id="id01"></div>
</body>
</html>
i solved it with
this code
var array =$.parseJSON(JSON.stringify(jsonString));
for (var i = 0; i < array.length; i++) {
var keys =array[i].tags;
var tags = Object.keys(keys);
for(var j = 0 ; j<tags.length; j++){
var obj = {text : tags[j], weight : keys[tags[j]] , link : array[i].url};
Jarray.push(obj);
}
}
The data is provided by an API, so the tag Event : 6 might be the next time Tomorrlowland : 3 the name of event and the weight are given by the API. That's why i can't use jsonString[0].tags.Event because the name event will be different every time.
Thanks all for helping me !

getJSON returning undefined

I'm trying to make an automatic news feed on a project website, where all the posts are put into a JSON file and then formatted on the news page accordingly. I've finally figured out how to get the json parser to show SOMETHING but that something is just a bunch of "undefined" bits all over the page. What am I doing wrong?
The jquery/html snippet
<script>
$.getJSON("js/news.json", function (data) {
$.each(data.posts, function (val) {
var title = val.title;
var date = val.date;
var content = val.content;
$("#newscontainer").append('<div><h1>' + title + '</h1><h2>' + date + '</h2><p>' + content + '</p></div>');
});
});
</script>
<div id='newscontainer'>
</div>
The JSON snippet
{
"posts": [
{
"title": "title1",
"date": "8302014",
"content": "LotsoftextLotsoftext"
},
{
"title": "title2",
"date": "8312014",
"content": "CopiousquantitiesoftextCopiousquantitiesoftext"
},
{
"title": "title3",
"date": "8322014",
"content": "onlyalittletext"
}
]
}
val in your code is the index, you should use the second argument of the callback.
$.each(data.posts, function (index, val) {
You can also use the this keyword.
Try this one :
var post_title = val.title;
var post_date = val.date;
var post_content = val.content;
var divTag = document.createElement("div");
newscontainer.appendChild(divTag);
var h1Tag = document.createElement("h1");
h1Tag.innerHTML = post_title;
newscontainer.appendChild(h1);
var h2Tag = document.createElement("h2");
h2Tag.innerHTML = post_date;
newscontainer.appendChild(h2);
var pTag = document.createElement("p");
pTag.innerHTML = post_content;
newscontainer.appendChild(p);
You can use the each() function on your list:
$(data.posts).each(function() {
var $this = this;
$("#newscontainer").append('<div><h1>' + $this.title + '</h1><h2>' + $this.date + '</h2><p>' + $this.content + '</p></div>');
});

How do I iterate over a JSON structure? [duplicate]

This question already has answers here:
Loop (for each) over an array in JavaScript
(40 answers)
Closed 5 years ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
I have the following JSON structure:
[{ "id":"10", "class": "child-of-9" }, { "id": "11", "classd": "child-of-10" }]
How do I iterate over it using JavaScript?
var arr = [ {"id":"10", "class": "child-of-9"}, {"id":"11", "class": "child-of-10"}];
for (var i = 0; i < arr.length; i++){
document.write("<br><br>array index: " + i);
var obj = arr[i];
for (var key in obj){
var value = obj[key];
document.write("<br> - " + key + ": " + value);
}
}
note: the for-in method is cool for simple objects. Not very smart to use with DOM object.
Taken from jQuery docs:
var arr = [ "one", "two", "three", "four", "five" ];
var obj = { one:1, two:2, three:3, four:4, five:5 };
jQuery.each(arr, function() {
$("#" + this).text("My id is " + this + ".");
return (this != "four"); // will stop running to skip "five"
});
jQuery.each(obj, function(i, val) {
$("#" + i).append(document.createTextNode(" - " + val));
});
Use for...of:
var mycars = [{name:'Susita'}, {name:'BMW'}];
for (var car of mycars)
{
document.write(car.name + "<br />");
}
Result:
Susita
BMW
Please let me know if it is not easy:
var jsonObject = {
name: 'Amit Kumar',
Age: '27'
};
for (var prop in jsonObject) {
alert("Key:" + prop);
alert("Value:" + jsonObject[prop]);
}
If this is your dataArray:
var dataArray = [{"id":28,"class":"Sweden"}, {"id":56,"class":"USA"}, {"id":89,"class":"England"}];
then:
$(jQuery.parseJSON(JSON.stringify(dataArray))).each(function() {
var ID = this.id;
var CLASS = this.class;
});
Copied and pasted from http://www.w3schools.com, there is no need for the JQuery overhead.
var person = {fname:"John", lname:"Doe", age:25};
var text = "";
var x;
for (x in person) {
text += person[x];
}
RESULT: John Doe 25
mootools example:
var ret = JSON.decode(jsonstr);
ret.each(function(item){
alert(item.id+'_'+item.classd);
});
You can use a mini library like objx - http://objx.googlecode.com/
You can write code like this:
var data = [ {"id":"10", "class": "child-of-9"},
{"id":"11", "class": "child-of-10"}];
// alert all IDs
objx(data).each(function(item) { alert(item.id) });
// get all IDs into a new array
var ids = objx(data).collect("id").obj();
// group by class
var grouped = objx(data).group(function(item){ return item.class; }).obj()
There are more 'plugins' available to let you handle data like this, see http://code.google.com/p/objx-plugins/wiki/PluginLibrary
With nested objects, it can be retrieve as by recursive function:
function inside(events)
{
for (i in events) {
if (typeof events[i] === 'object')
inside(events[i]);
else
alert(events[i]);
}
}
inside(events);
where as events is json object.
Marquis Wang's may well be the best answer when using jQuery.
Here is something quite similar in pure JavaScript, using JavaScript's forEach method. forEach takes a function as an argument. That function will then be called for each item in the array, with said item as the argument.
Short and easy:
var results = [ {"id":"10", "class": "child-of-9"}, {"id":"11", "classd": "child-of-10"} ];
results.forEach(function(item) {
console.log(item);
});
this is a pure commented JavaScript example.
<script language="JavaScript" type="text/javascript">
function iterate_json(){
// Create our XMLHttpRequest object
var hr = new XMLHttpRequest();
// Create some variables we need to send to our PHP file
hr.open("GET", "json-note.php", true);//this is your php file containing json
hr.setRequestHeader("Content-type", "application/json", true);
// Access the onreadystatechange event for the XMLHttpRequest object
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var data = JSON.parse(hr.responseText);
var results = document.getElementById("myDiv");//myDiv is the div id
for (var obj in data){
results.innerHTML += data[obj].id+ "is"+data[obj].class + "<br/>";
}
}
}
hr.send(null);
}
</script>
<script language="JavaScript" type="text/javascript">iterate_json();</script>// call function here
var jsonString = `{
"schema": {
"title": "User Feedback",
"description": "so",
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"options": {
"form": {
"attributes": {},
"buttons": {
"submit": {
"title": "It",
"click": "function(){alert('hello');}"
}
}
}
}
}`;
var jsonData = JSON.parse(jsonString);
function Iterate(data)
{
jQuery.each(data, function (index, value) {
if (typeof value == 'object') {
alert("Object " + index);
Iterate(value);
}
else {
alert(index + " : " + value);
}
});
}
Iterate(jsonData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Another solution to navigate through the JSON document is JSONiq (implemented in the Zorba engine), where you can write something like this:
let $doc := [
{"id":"10", "class": "child-of-9"},
{"id":"11", "class": "child-of-10"}
]
for $entry in members($doc) (: binds $entry to each object in turn :)
return $entry.class (: gets the value associated with "class" :)
You can run it on http://public.rumbledb.org:9090/public.html

Categories