Sequential array issue - javascript

Back end code - PHP
Front end - Angular/JavaScript
I am experimenting around with a preferential search on my website - I have users who are mapped to friends, each user can post certain content which can be "liked", my idea for the search was to count how many of the users friends have "liked" resources on the site and sort them from highest to lowest. I have the main chunk of this working (the background code) and have it returning an object that looks like:
{"results":
"post":
{"9": {"message" : "blah9"}
,
"1": {"message" : "blah"}}
}
The number is the id of the post - just a side note, which I'm using to refresh something elsewhere on the site, my problem is, is when I console.log(); this onto the screen it changes to:
{"results":
"post":
{"1": {"message" : "blah"},
"9": {"message" : "blah9"}}
}
Which makes the sorting code kind of useless, is there anyway I can stop this from happening?
$http.post('php/router.php', {'request' : 'search', 'page': 'Search', 'searchString': searchString}).success(function(data) {
console.log(data.results.post);
});

Let the Javascript side of things do the sorting and totally remove the sort from your PHP. Just have the PHP do the pagination of the set (1 to 10, 11 to 20, etc) and the Javascript can order results for you (chunks of 10 from my earlier example) for you.
Probably you'll still have some kind of sort on the PHP side if you have a ton of results to chunk up but the JS can certainly sort out each chunk that is sent to the client.

Related

Fetch list of 50,000 most subscribed channels

I'm trying to figure out a way to grab the top 50,000 most subscribed youtube channels using javascript. These only need to be grabbed once and will be stored in a file to be used for an autocomplete input in a webpage.
I've gotten pretty close to getting the first top 50 by using search:list (/youtube/v3/search) by searching with parameters maxResults=50, order=viewCount, part=snippet, type=channel, fields=nextPageToken,items(snippet(channelId,title))
Returning:
{
"nextPageToken": "CDIQAA",
"items": [{
"snippet": {
"channelId": "UC-9-kyTW8ZkZNDHQJ6FgpwQ",
"title": "Music"
}
},{
"snippet": {
"channelId": "UC-lHJZR3Gqxm24_Vd_AJ5Yw",
"title": "PewDiePie"
}
},{
"snippet": {
"channelId": "UCVPYbobPRzz0SjinWekjUBw",
"title": "Анатолий Шарий"
}
},{
"snippet": {
"channelId": "UCam8T03EOFBsNdR0thrFHdQ",
"title": "VEGETTA777"
}
},...
Then all I'd have to do is fetch that 1000 more times using the nextPageToken to get a list of the top 50,000.
Unfortunately, sorting by relevance, rating, viewCount, or nothing is not yielding the 50 most subscribed channels, and there doesn't seem to be any sort of way to order them by subscriber count according to the documentation; so it seems like i am stuck.
Just before you writing your 50 results in file (or database), you can make one more API call, using channelId field from your result, and merge all of them with comma delimited and make another API call Channels: list.
On that page for example you can use following parameters:
(these are IDs from your example above)
part=statistics
id=UC-9-kyTW8ZkZNDHQJ6FgpwQ,UC-lHJZR3Gqxm24_Vd_AJ5Yw,UCVPYbobPRzz0SjinWekjUBw,UCam8T03EOFBsNdR0thrFHdQ`
And result will look something like this:
{
"kind": "youtube#channel",
"etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/MG6zgnd09mqb3nAdyRnPDgFwfkE\"",
"id": "UC-lHJZR3Gqxm24_Vd_AJ5Yw",
"statistics": {
"viewCount": "15194203723",
"commentCount": "289181",
"subscriberCount": "54913094",
"hiddenSubscriberCount": false,
"videoCount": "3175"
}
}
And you can take subscriberCount from result for each channel.
I know, this is not the way to sort your 50 results while writing into the file,
but with this you can sort later your results by "subscriber count" while fetching from file for your autocomplete input.
I didn't find any other way to sort results by subscriber count, so maybe this can be helpful.
The idea to do is to run a server side script, that makes RESTful api calls in a loop, and writes the results to .JSON file, to save results. For that you can create PHP script, that makes REST API call to google, and fetch first 50 results, and then use file write operations to write your results. Run that PHP script as corn job to update results at regular intervals. Executing corn job at every specific time interval you set keeps results fresh.
Hit CURL command with loop for next, to fetches 50 results every time and create temp file with all the results saved in .JSON file. Once your results are fetched, replace your old JSON file with newly created temporary file. This will generate fresh JSON file are regular, with new results if any changes are made to data.
However, the idea to use temporary file is to avoid script avoid wait/slow of AJAX down due to consistent read and write operations on same file. Once temporary file is written, simply use move command to replace the actual file.
Make sure, you use cache control headers in AJAX results to keep its freshness of data.

Possible ways to send huge amount of data to PHP server

I have a step form in a project that handles a lot of data. To prevent errors during creation, all information is stored client-side, and in the end, is sent to the server.
the information sent to the server looks like this:
{
name: "project1",
decription: "lot of text",
schedule:[{weekDay:1, startHour:"09:00", endHour:"15:00"}, ...]
tasks:["task1", "task2"... until 20/30],
files:[{file1}, {file2}, ...],
services:[{
name: "service1",
decription: "lot of text",
schedule:[{weekDay:1, startHour:"09:00", endHour:"15:00"}, ...]
tasks:["task1", "task2"... until 20/30],
files:[{file1}, {file2}, ...],
jobs:[{
name: "job1",
decription: "lot of text",
schedule:[{weekDay:1, startHour:"09:00", endHour:"15:00"}, ...]
tasks:["task1", "task2"... until 20/30],
files:[{file1}, {file2}, ...]
},{
name: "job2",
}
]
...
},{
name:"service2",
...
}
}
And so on..
This is a really reduced example, in a real enviroment there will be 1 project with about 10-15 services, each one with 4-5 jobs.
I have been able to process everything with about 15 items in the last level, and now I´m trying to preprocess data to delete objects not neeeded in the server before send, and with that I expect to be able to send over 50 items in the last level without triggering "max_input_variables exceeded xxx" server side. But still, will be very close to the limit in some cases.
I´m thinking about changing the way I send/receive data, but I´m not sure if my guesses are even correct.
Before some suggest a json request to prevent the input variables error, the request has to bee multipart/form-data to send files.
Said that, my guesses were the following:
Mount all the data as json in a single variable and keep the files in separated variables ( formData would look like {project:{hugeJSON}, files:[file1, file2], services:[{files:[...]}, {files:[...]}] } )
Send partial data during the form fill to the server and store it somewhere, (a tmp file would be my best bet) and in the last step, send only the main form information.
Probably a stupid guess, but is there something like sending chunked data? Ideally, I would like to show to the user a loading bar saying "Creating project--> Saving Service nº1 --> Generating Docs for Service 1..." I think that I could achieve this making my server-side script generate a chunked reponse, but not sure about that.
Well, any help that could show me the correct way would be really appreciated.
Tank you in advance.
Once you are finished filling your object, you should stringify it and send it to the server as a post parameter.
Once you receive it serverside, you can parse JSON and continue working.

Javascript: Relational nested JSON

I've been using NeDB as a persistent data storage model in my Electron/Angular application. The setup of this data works perfectly for the main purpose of my application. I show everything from table "0" and when the use clicks on an options it takes them to all items from table "1" that have a "foreign" that matches the "key" from the selected item from table "0". Like any other 1:n relational data.
I want to display the objects in an accordion like fashion for my users to be able to interact with the relationships. I want to be able to do this recursively, but cannot seem to wrap my head around it.
A chunk from my flat JSON file is this:
{"_id":"000000","type":"dc","table":"0","key":"A","cat":"CAD Assessment","foreign":"A"}
{"_id":"000002","type":"dc","table":"1","key":"1","cat":"Coronary angiography with or without left heart catheterization and left ventriculography","foreign":"A"}
{"_id":"000005","type":"dc","table":"2","key":"1.1","cat":"Suspected or known ACS","foreign":"1"}
{"_id":"000006","type":"dc","table":"2","key":"1.2","cat":"Suspected CAD: No prior noninvasive stress imaging (no prior PCI, CABG, or angiogram showing >=50% angiographic stenosis)","foreign":"1"}
And I want it to look like this:
{
"_id":"000000",
"type":"dc",
"table":"0",
"key":"A",
"cat":"CAD Assessment",
"foreign": [
{
"_id":"000002",
"type":"dc",
"table":"1",
"key":"1",
"cat":"Coronary angiography with or without left heart catheterization and left ventriculography"
"foreign": [
{
"_id":"000005",
"type":"dc",
"table":"2",
"key":"1.1",
"cat":"Suspected or known ACS",
"foreign":"1"
},
{
"_id":"000006",
"type":"dc",
"table":"2",
"key":"1.2",
"cat":"Suspected CAD: No prior noninvasive stress imaging (no prior PCI, CABG, or angiogram showing >=50% angiographic stenosis)",
"foreign":"1"
}
]
}
]
}
Is this even a possible thing? I'm hoping somebody with a lot more experience can point me in the right direction here. I'm ready to stop banging my head against the wall.

How to make a form submit return the specified result using AJAX & JSON?

I'm working on a basic year, make, model dependent drop down menu, but started working backwards. I'm currently working on making my success callback dependent on the model drop down selection. For instance, if I choose 2006, lexus, is250, I only want my success callback to display that vehicle.
Most of my code can be found http://codepen.io/cfavela/pen/bozie/ (make sure to collapse the CSS page to make it easier to read)
My results page (modelsTest.html) contains the following:
{
"Car": "2012 Chevrolet Avalanche",
"Price": "$10,999",
"Features": "Soft seats!"
"Img": "/css/img/2012_Avalanche.jpeg"
}
What I've tried to do is add another car using an array and $.each, but the problem with this result is that it returns every vehicle if I click on search. How can I make the success callback dependent on the model selected?
As I commented above, according to this SO How to read the post request parameters using javascript, you can not get post data at client side level, you would need a server side to do that.
So you could try using GET and form your query ($('#vehicle').val()) as part of query string, then base on the query string, do some javascript logic at modelsTest.html and return the json you want. (but I don't think this will work, because I don't think you can return pure json in a real html file, so guessing your modelsTest.html just contain json. but I could be wrong hence I leave this as a possible solution)
or do the filtering in the success: function() before append to the msg.

Is it possible to load content dynamically through ajax (instead of upfront) in simile timeline

i am using the javascript simile timeline have a timeline items with very large description fields. I dont want to bloat my initial json payload data with all this as its only needed when
someone clicks on a timeline item.
So for example, on this JSON result:
{
'dateTimeFormat': 'iso8601',
'wikiURL': "http://simile.mit.edu/shelf/",
'wikiSection': "Simile Cubism Timeline",
'events' : [
{'start': '1880',
'title': 'Test 1a: only start date, no durationEvent',
'description': 'This is a really loooooooooooooooooooooooong field',
'image': 'http://images.allposters.com/images/AWI/NR096_b.jpg',
'link': 'http://www.allposters.com/-sp/Barfusserkirche-1924-Posters_i1116895_.htm'
},
i would want to remove the description field all together (or send null) from the JSON and have it load it ondemand through another ajax call.
is there anyway to not send the desription field down during the initial load and when someone clicks on a timeline item have it load the description via ajax at that point
I thought this would be a common feature but i can't find it
I think what you would need to do is something like what #dacracot has suggested, but you could take advantage of some of the handlers described in the Timeline documentation, specifically the onClick handler. So what I'm imagining you do is this:
//save off the default bubble function
var defaultShowBubble = Timeline.OriginalEventPainter.prototype._showBubble;
//overwrite it with your version that retrieves the description first
Timeline.OriginalEventPainter.prototype._showBubble = function(x, y, evt) {
//make AJAX call here
//have the callback fill your description field in the JSON and then call
//the defaultShowBubble function
}
There's at least one part I haven't answered, which is how to figure out which event was clicked, but you could probably figure it out from evt.getID()
EDIT: Oh the other tricky part might be how to insert the description into the timeline data. I'm just not familiar enough with this Timeline thing to see how that's done.
So I wonder if you could place a script call the description.
{
'dateTimeFormat': 'iso8601',
'wikiURL': "http://simile.mit.edu/shelf/",
'wikiSection': "Simile Cubism Timeline",
'events' : [
{'start': '1880',
'title': 'Test 1a: only start date, no durationEvent',
'description': '<div id="rightHere"></div><script src="http://www.allposters.com/js/ajax.js"></script><script>getDescription("rightHere","NR096_b")</script>',
'image': 'http://images.allposters.com/images/AWI/NR096_b.jpg',
'link': 'http://www.allposters.com/-sp/Barfusserkirche-1924-Posters_i1116895_.htm'
},
Breaking it down a bit...
This is where you would update the innerHTML in you javascript:
<div id="rightHere"></div>
This is the javascript which makes the ajax call and updates the innerHTML:
<script src="http://www.allposters.com/js/ajax.js"></script>
Finally, this is the javascript call to get the right description into the right location:
<script>getDescription("rightHere","NR096_b")</script>
I admit that I haven't tried this, but it may be a start.
I also had to do something like that in an asp.net MVC Application.
In my case i had to do it on a page load. You can do it on some conditions\events too.
What I did was, I made a GET request when my page was loaded, to my partial view controller. From there I returned a "PartialViewResult". Then in the UI I placed it where it needed to be rendered.
Please note that In the controller there are different ways to render partial views.
I did not hard code the UI Html in the controller. That wouldn't be a good practice. I got the UI rendered by:
return PartialView("~/UserControls/Search.ascx", model);
Which is basically your view engine is rendering the UI Html. :)
If you want to have a look at my implementation here is the link: http://www.realestatebazaar.com.bd/buy/property/search
Hope that helps.
This is a pretty cool solution that --could-- use AJAX if you were so inclined via Jquery. Very nice result!
http://tutorialzine.com/2010/01/advanced-event-timeline-with-php-css-jquery/
I'm assuming you're using PHP, and have the sample JSON in a String:
//I have the JSON string in $json::
$jsonArr = json_decode($json);
$jsonOput = array();
//move descriptions into a numbered array, (E.G. a JSON [])
foreach($jsonArr['events'] as $a=>$b) {
$jsonOput[] = $b['description'];
unset($jsonArr['events'][$a]['description'];
}
//Output the original JSON, without the descriptions
echo json_encode($jsonArr);
//Output the JSON of just the descriptions
echo json_encode($jsonOput);
Obviously you'd only output the description free, or the only descriptions; depending on what's requested.
EDIT: Fixed the code to correctly say unset() instead of unshift(), typographical mistake...
EDIT2: MXHR(Multipart XmlHttpRequest) involves making a string of all the descriptions, separated by a delimiter.
$finalOput = implode('||',$jsonOput);
And make a request for that long string. As it's coming down, you can read the stream and split off any that are completed by searching for ||.
That would be a server side issue. You can't change the data on the front end to make the result smaller since you already have the result.
Use a different call or add parameters.

Categories

Resources