jQuery Promise each loop - javascript

I am creating a UserScript that will generate a list of URLs to a users photo gallery. A user gallery may have multiple pages, each page has multiple thumbnails that have a link to a page which contains the full-sized image url.
I am using jQuery to request the pages though I'm not getting the desired results when a user gallery only contains 1 page. I get some results when a user gallery contains multiple pages but I only get 1 page worth of results.
var userID = 0;
function getUserID() {
var query = window.location.search;
var regex = /UserID=(\d+)/;
var regexResult = query.match(regex);
if (regexResult !== null) {
return regexResult[0].replace('UserID=', '');
} else {
return 0;
}
}
function getGallery(userID) {
function getGalleryPage(userID, page, gallery) {
var data = {};
if(page > 0) {
data = { btnNext: ">", PageNo: page };
}
var url = 'http://www.domain.com/' + userID;
return $.ajax({
method: 'POST',
url: url,
data: data,
dataType: 'html'
}).then(function(result){
$result = $(result);
$result.find('form[name="frmGallery"]').find('img').each(function() {
var url = ''
// Do stuff to get url
getGalleryImage(url).done(function(imageLink) {
gallery.push(imageLink);
});
});
$btnNext = $result.find('input[name="btnNext"]');
if($btnNext.length > 0) {
page += 1;
return getGalleryPage(userID, page, gallery);
} else {
return(gallery);
}
});
}
return getGalleryPage(userID, 0, []);
}
function getGalleryImage(url) {
return $.ajax({
method: 'GET',
url: url,
dataType: 'html'
}).then(function(result){
var imageUrl = '';
// Do stuff to get full sized image url
return imageUrl;
});
}
jQuery(document).ready(function($) {
userID = getUserID();
if(userID === 0)
return;
getGallery(userID).done(function(gallery) {
$.each(gallery, function(index, value) {
console.log(value);
});
});
});
I think this part of my script is not correct:
$result.find('form[name="frmGallery"]').find('img').each(function() {
var url = ''
// Do stuff to get url
getGalleryImage(url).done(function(imageLink) {
gallery.push(imageLink);
});
});

As written, there's no attempt to aggregate the inner promises returned by getGalleryImage().
You need to map the delivered img elements to an array of promises and aggregate them with jQuery.when().
I would write it something like this :
jQuery(function($) {
var userID;
function getUserID() {
var query = window.location.search;
var regex = /UserID=(\d+)/;
var regexResult = query.match(regex);
if (regexResult !== null) {
return regexResult[0].replace('UserID=', '');
} else {
return 0;
}
}
function getGallery(userID) {
var gallery = [];
var page = 0;
var url = 'http://www.domain.com/' + userID;
function getGalleryPage() {
var data = (page > 0) ? { btnNext: ">", PageNo: page } : {};
return $.ajax({
method: 'POST',
url: url,
data: data,
dataType: 'html'
}).then(function(result) {
$result = $(result);
//map jQuery collection of img elements to Array of promises
var promises = $result.find('form[name="frmGallery"]').find('img').map(function(imgElement, i) {
var url = ''
// Do stuff to get url
return getGalleryImage(url);
}).get();// .get() is necessary to unwrap jQuery and return Array
//aggregate promises
return $.when.apply(null, promises).then(function() {
//accumulate results
gallery = gallery.concat(Array.prototype.slice.call(arguments));
// recurse/terminate
if($result.find('input[name="btnNext"]').length > 0) {
page += 1;
return getGalleryPage();
} else {
return gallery;
}
});
});
}
return getGalleryPage();
}
function getGalleryImage(url) {
return $.ajax({
method: 'GET',
url: url,
dataType: 'html'
}).then(function(result) {
var imageUrl = '';
// Do stuff to get full sized image url
return imageUrl;
});
}
userID = getUserID();
if(userID !== 0) {
getGallery(userID).then(function(gallery) {
$.each(gallery, function(index, value) {
console.log(value);
});
});
}
});
You should also impose a limit on the number of recursions, just in case one day some userID yields thousands of pages.

Related

I want to filter the serial in replace and return if it is used in repair

I tried this
$.ajax({
url: '/api/serials/index/',
method: 'GET',
data: {
reference_no: $(this).val()
},
success: function (response) {
let items_repairs = response[items_repairs];
let items_replaces = response[items_returns];
$('#repair_serial_no').empty().append('<option></option>');
let filteredResponse = response[0].filter(function(item) {
//Check if the serial is already used in the repair and return table
let usedInRepair = items_repairs.serial_no.indexOf(item.serial_no) !== -1;
let usedInReplaces = items_replaces.serial_no.indexOf(item.serial_no) !== -1;
if(!usedInRepair && !usedInReplaces) {
return item;
}
});
filteredResponse.forEach(item => {
let template = `<option value="${item.id}">${item.serial_no}</option>`;
$('#return_serial_no').append(template);
});
but when i click the click the select there is no serial showing
in my /api/serials/index/
public function index(Request $request)
{
$serials = SerialNumber::where('reference_no', $request->reference_no)->get(['id', 'serial_no']);
$items_repairs = ItemsRepair::all();
$items_returns = ItemsReturn::all();
$items_replaces = ItemsReplace::all();
return response()->json([$serials,$items_repairs,$items_returns,$items_replaces]);
I think you forgot to set the key as a string.
$.ajax({
...
success: function (response) {
let items_repairs = response['items_repairs'];
let items_replaces = response['items_returns'];
...
}

How to add dynamically attribute value using Jquery?

I have logic where i am trying to add host url dynamically so it work in all env based on hosst, so below trying to find a file that is there in host but its never going into $.each statement , if call url directly http://18.35.168.87:6000/Sdk/wrapper-sdk/client/out.json it worked and rendered data, any idea what could have wrong in below code to achieve this task ?
main.js
function myFunction(val) {
var url = "../../wrapper-sdk/" + client + "/out.json";
if (window.location.hostname.indexOf("localhost") !== -1 ||
window.location.host.indexOf("localhost") !== -1) {
var scripts = document.getElementsByTagName('script');
var host = '';
$.each(scripts, function (idx, item) {
if (item.src.indexOf('Sdk/wrapper-sdk') !== -1 && (item.src.indexOf('out.json') !== -1)) {
host = item.src.split('?')[0];
host = host.replace('wrapper-sdk/' + client + '/out.json', '');
}
});
url = url.replace('../../', host);
}
$.ajax({
url: url + "?no_cache=" + new Date().getTime(),
dataType: "json",
"async": false,
success: function (data) {
console.log(data);
},
error: function () {
console.log('error while accessing api.json.')
}
});
}
I would suggest breaking up some of your checks into their own function. Makes it just a bit easier to follow the logic.
function validIp(str) {
var parts = str.split(".");
var result = true;
$.each(parts, function(i, p) {
if (parseInt(p) > 0 && parseInt(p) < 255) {
result = result && true;
}
});
return result;
}
function checkLocalUrl(str) {
var result = 0;
if (str.indexOf("localhost") >= 0) {
result = 1;
}
if (validIp(str)) {
result = -1;
}
/*
0 = Some Domain or Host Name, not LocalHost
1 = LocalHost
-1 = IP Address
*/
return result;
}
function changeSources(client) {
if (checkLocalUrl(window.location.hostname) || checkLocalUrl(window.location.host) {
var scripts = $("script");
var host = '';
scripts.each(function(i, el) {
var src = $(el).attr("src");
var nUrl = new URL(src);
var pro = nUrl.protocol;
var hn = nUrl.hostname;
if (nUrl.pathname.indexOf('/Sdk/wrapper-sdk') == 0 && nUrl.pathname.indexOf('out.json') > 0) {
host = pro + "://" + hn + "/wrapper-sdk/" + client + "/out.json";
}
$.ajax({
url: host
data: { no_cache: new Date().getTime() },
dataType: "json",
async: false,
success: function(data) {
console.log(data);
},
error: function() {
console.log('error while accessing api.json.')
}
});
});
}
}
}
See also: new URL()
You can send a string to checkLocalUrl() and it will return 1 or true if it's potentially a localhost URL. It will return 0 or false if it's any other domain pattern or -1 or false if it's an IP address.
In changeSources() we can use this to check for local urls and perform the AJAX you defined.

Iterate over array items and check property value

function GetViewModelData() {
var RDcViewModel = [];
var recordId = $.trim($("#recordId").val());
for (i = 1; i <= rowCount; i++) {
var item1 = $.trim($("#item1" + i).val()) == '' ? 0 : parseInt($("#item1" + i).val());
var item2 = $.trim($("#item2" + i).val()) == '' ? 0 : parseInt($("#item2" + i).val());
var GrandTotal = (item1 + item2);
var rdtCViewModel = new ItemDetailsViewModel(0, item1, item2, GrandTotal);
RDcViewModel.push(rdtCViewModel);
}
var obj = new ReportViewModel(recordId, RDcViewModel);
var viewmodel = JSON.stringify(obj);
return viewmodel;
}
I have the above sample function that i'm using to iterate over html table rows and storing the row values in an array.
Once i have my array populated, i'm using below code snippet to post the data to my controller.
var PostData = function () {
$(".btnSubmit").click(function () {
var viewmodel = GetViewModelData();
//i want to check from here if viewmodel has any item(row) where GrandTotal is 0 (zero)
$.ajax({
async: true,
cache: false,
contentType: 'application/json; charset=utf-8',
data: viewmodel,
headers: GetRequestVerificationToken(),
type: 'POST',
url: '/' + virtualDirectory + '/Item/DataSave',
success: function (data) {
if (data == true) {
window.location.href = '/' + virtualDirectory + '/Destination/Index';
}
},
error: function (e) {
return false;
}
});
});
}
What i now want to do in my PostData function is to check if my "viewmodel" object contains any item(row) where "GrandTotal" is 0.
using JSON.parse(viewmodel), prepare object of type ReportViewModel with RDcViewModel JS array of type ItemDetailsViewModel and iterate over it to find if any grandtotal == 0 for ItemDetailsViewModel instances
var viewmodel = GetViewModelData(),
var obj = JSON.parse(viewmodel);
var bFoundZero=false;
$.each(obj.RDcViewModelArray, function(idx, elem){
if( elem.GrandTotal === 0 ) bFoundZero=true;
})
if( bFoundZero ) return 0;
As you have stringified it, now you have to parse it back if you want to access its keys and values:
var PostData = function() {
$(".btnSubmit").click(function() {
var viewmodel = GetViewModelData(),
viewObj = JSON.parse(viewmodel),
flag = false; // <-----parse it back here
viewObj.forEach(function(i, el){
flag = el.GrandTotal === 0;
return flag;
});
if(flag){ return false; } // <------ and stop it here.
$.ajax({
async: true,
cache: false,
contentType: 'application/json; charset=utf-8',
data: viewmodel,
headers: GetRequestVerificationToken(),
type: 'POST',
url: '/' + virtualDirectory + '/Item/DataSave',
success: function(data) {
if (data == true) {
window.location.href = '/' + virtualDirectory + '/Destination/Index';
}
},
error: function(e) {
return false;
}
});
});
}
There is no point iterating array again. Break the loop in GetViewModelData() and return false from that function. Then test it in PostData
Inside existing for loop:
var GrandTotal = (item1 + item2);
if(!GrandTotal){
return false;
}
Then in PostData()
var PostData = function () {
$(".btnSubmit").click(function () {
var viewmodel = GetViewModelData();
if(viewmodel === false){
alert('Missing total');
return; //don't proceed
}
/* your ajax */

Backbone trigger() returning typeError

I keep getting the following error from calling an event from my model:
window.Playlist = new PlaylistModel();
Playlist.trigger("playerPlaying");
`Uncaught TypeError: Cannot read property '0' of undefined`
My stack trace:
Uncaught TypeError: Cannot read property '0' of undefined
triggerEventsbackbone.js:206
Backbone.Events.triggerbackbone.js:148
onPlayerStateChangeplayer.js:101
g.Iwww-widgetapi-vfldqBTcy.js:13
g.kwww-widgetapi-vfldqBTcy.js:22
g.Jwww-widgetapi-vfldqBTcy.js:30
X.dwww-widgetapi-vfldqBTcy.js:29
Qa.fwww-widgetapi-vfldqBTcy.js:18
I dig in backbone source code and find the following
trigger: function(name) {
if (!this._events) return this;
var args = slice.call(arguments, 1);
if (!eventsApi(this, 'trigger', name, args)) return this;
var events = this._events[name];
var allEvents = this._events.all;
if (events) triggerEvents(events, args);
if (allEvents) triggerEvents(allEvents, arguments);
return this;
I printed the lines one by one after setting a breakpoint from chrome console.
arguments = ["playerPlaying"]
args = []
this._events = Object {change:currentSong: Array[3], change:loopActive: Array[3], playerPlaying: Array[3]}
events = [Object, Object, Object]
this = the Backbone model on which `trigger()` was called
I think the problem is that arguments should be [ModelThatTriggeredEvent, eventName] but I am only getting [eventName] so args becomes an empty array. Does anyone know why this is happening?
Update:
Here's the entire PlaylistModel with some parts deleted. Please understand the mess in the code as I am in the middle of refactoring it to abide by the Backbone way of doing things.
define([
// These are path alias that we configured in our bootstrap
'jquery', // lib/jquery/jquery
'backbone',
'../../common/models/song',
'../collections/songs'
], function($, Backbone, Song, Songs){
window.AVAILABLE_CHARTS = {
billboardChart: {
source: "billboard",
chart: [
{genre: chrome.i18n.getMessage("pop"), url: 'http://www.billboard.com/rss/charts/hot-100'},
{genre: chrome.i18n.getMessage("rock"), url: "http://www.billboard.com/rss/charts/rock-songs"},
]
}
};
var Playlist = Backbone.Model.extend({
defaults: {
currentSong: null,
nextSong: null,
prevSong: null,
genre: null, // initial genre
loopActive: false,
shuffleActive: false,
numSongs: 10, // initial number of songs loaded
musicChart: null
},
initialize: function() {
// Setting collections/songs as its attribute
var songs = new Songs();
this.set('songs', songs);
var userLocale = chrome.i18n.getMessage("##ui_locale");
if (userLocale == "ko" || userLocale == 'ko-kr') {
this.set('musicChart', AVAILABLE_CHARTS.melonChart);
this.set('genre', this.get('musicChart').chart[0].genre);
} else {
this.set('musicChart', AVAILABLE_CHARTS.billboardChart);
this.set('genre', this.get('musicChart').chart[0].genre);
}
},
// If loop is active, getNextSong repeats the current song
// If shuffle is active, getNextSong plays a random song from Songs
getNextSong: function() {
//var idx = this.indexOf(this.getCurrentSong());
var songs = this.get('songs');
var idx = songs.indexOf(songs.findWhere({ title: this.get('currentSong').get('title') }));
if (this.get('loopActive')) {
return songs.at(idx);
}
if (this.get('shuffleActive')) {
var randomIndex = Math.floor((Math.random()*songs.length));
return songs.at(randomIndex);
}
if (idx != songs.length-1) return songs.at(idx+1);
else return songs.at(0);
},
getPrevSong: function() {
var songs = this.get('songs');
var idx = songs.indexOf(songs.findWhere({ title: this.get('currentSong').get('title') }));
if (idx != 0) return songs.at(idx-1);
else return songs.at(songs.length-1);
},
// Get new songs from Billboard Chart
// First parse the top <numSongs> from the selected <genre>
// from Billboard, and then use YouTube gdata api to fetch
// the songs.
getNewSongs: function (callback, genre, numSongs) {
// FIXME: just trigger progress
var popupWindow = chrome.extension.getViews({ type: "popup" })[0];
if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(10);
var playlist = this;
playlist.get('songs').reset();
// Inspect Billboard Chart to find pop songs
$.get(url+numSongs+'/explicit=true/xml', function (data) {
var popupWindow = chrome.extension.getViews({ type: "popup" })[0];
if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(30);
var $feed = $(data).find('feed')
var $entries = $feed.find('entry')
var numAvailableSongs = $entries.length;
$entries.each(function (idx, entry) {
var title_artist_pair = $(entry).find('title')[0].innerHTML;
var title = $.trim(title_artist_pair.split(' - ')[0]);
var artist = $.trim(title_artist_pair.split(' - ')[1]);
var rank = idx+1;
var query = title + " " + artist;
_searchYouTube(title, artist, rank, query, numAvailableSongs);
});
return;
});
}
function _searchYouTube (title, artist, rank, query, numAvailableSongs) {
var songs = playlist.get('songs');
$.ajax({
url: searchUrl,
type: "GET",
data: 'q='+encodeURIComponent(query),
success: function (result) {
//console.log("\n**** 검색: "+query);
ajaxCount += 1;
if (result.items.length)
var videoId = result.items[0].id.videoId;
else
var videoId = null; // Cannot find the song on YouTube
var song = new Song({
title: title,
artist: artist,
rank: parseInt(rank),
query: query,
videoId: videoId
});
// Insert songs into the playlist in the order of their ranks
// *Note: Songs that do not exist on YouTube are ignored
if (videoId) songs.add(song, { silent: true });
// All the ajax calls are finished
if (ajaxCount == numAvailableSongs) {
var popupWindow = chrome.extension.getViews({ type: "popup" })[0];
if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(70);
songs.comparator = 'rank'
songs.sort();
// Remove useless playlsit methods
if (!playlist.get('currentSong')) {
playlist.set('currentSong', songs.at(0));
}
callback();
}
},
error: function (error) {
ajaxCount += 1;
if (ajaxCount == numAvailableSongs) {
var popupWindow = chrome.extension.getViews({ type: "popup" })[0];
if (popupWindow) popupWindow.popupView.setProgress(70);
if (!playlist.get('currentSong')) {
playlist.set('currentSong', songs.at(0));
}
callback();
}
} // end of error
}); // end of second ajax
} // end of _searchYouTube()
},
lookUpAndAddSingleSong: function (query) {
var playlist = this;
var youtubeAPIKey = "fdf";
var initialSearchURL = "df";
var searchUrl = initialSearchURL + "&key=" + youtubeAPIKey;
$.ajax({
url: searchUrl,
type: "GET",
data: 'q='+encodeURIComponent(query),
success: function (result) {
if (result.items.length) {
var videoId = result.items[0].id.videoId;
var song = new Song({
title: result.items[0].snippet.title,
query: query,
videoId: videoId
});
} else var videoId = null; // Cannot find the song on YouTube
if (videoId) {
playlist.get('songs').add(song);
song.save(); // save to localStorage
}
}, error: function (xhr, status, errorThrown) {
var errorMessage = "lookUpAndAddSingleSong error: check http://instantmusicapp.com";
var popupWindow = chrome.extension.getViews({ type: "popup" })[0];
if (popupWindow && popupWindow.popupView) popupWindow.showErrorMessage(errorMessage);
return;
}
});
},
setMusicChart: function (chartName) {
// if the chart is provided, we pick from Melon, Billboard, iTunes
if (chartName) {
if (chartName == chrome.i18n.getMessage("melonChart"))
this.set('musicChart', AVAILABLE_CHARTS.melonChart);
else if (chartName == chrome.i18n.getMessage("billboardChart"))
this.set('musicChart', AVAILABLE_CHARTS.billboardChart);
else
this.set('musicChart', AVAILABLE_CHARTS.itunesChart);
// else, the user is looking for a personal favorite chart
} else {
this.set('musicChart', AVAILABLE_CHARTS.myChart);
}
},
});
return Playlist;
});
There are quite a few syntax errors in your model which is probably why you are being prevented from issuing a trigger with or even anything else from your bb model.
line 14 has a dangling comma (,) for instance.
try running your model through JSLint or JSHint and fixing the errors. will probably fix your issue
Dangling comma is acceptable in most of the browsers, but actual error was an extra } after getNewSongs function. I suggest using some IDE/Editor which supports JSHint integration. You can try webstorm. Here is the updated code.
define([
// These are path alias that we configured in our bootstrap
'jquery', // lib/jquery/jquery
'backbone',
'../../common/models/song',
'../collections/songs'
], function ($, Backbone, Song, Songs) {
window.AVAILABLE_CHARTS = {
billboardChart: {
source: "billboard",
chart: [
{genre: chrome.i18n.getMessage("pop"), url: 'http://www.billboard.com/rss/charts/hot-100'},
{genre: chrome.i18n.getMessage("rock"), url: "http://www.billboard.com/rss/charts/rock-songs"},
]
}
};
var Playlist = Backbone.Model.extend({
defaults: {
currentSong: null,
nextSong: null,
prevSong: null,
genre: null, // initial genre
loopActive: false,
shuffleActive: false,
numSongs: 10, // initial number of songs loaded
musicChart: null
},
initialize: function () {
// Setting collections/songs as its attribute
var songs = new Songs();
this.set('songs', songs);
var userLocale = chrome.i18n.getMessage("##ui_locale");
if (userLocale == "ko" || userLocale == 'ko-kr') {
this.set('musicChart', AVAILABLE_CHARTS.melonChart);
this.set('genre', this.get('musicChart').chart[0].genre);
} else {
this.set('musicChart', AVAILABLE_CHARTS.billboardChart);
this.set('genre', this.get('musicChart').chart[0].genre);
}
},
// If loop is active, getNextSong repeats the current song
// If shuffle is active, getNextSong plays a random song from Songs
getNextSong: function () {
//var idx = this.indexOf(this.getCurrentSong());
var songs = this.get('songs');
var idx = songs.indexOf(songs.findWhere({ title: this.get('currentSong').get('title') }));
if (this.get('loopActive')) {
return songs.at(idx);
}
if (this.get('shuffleActive')) {
var randomIndex = Math.floor((Math.random() * songs.length));
return songs.at(randomIndex);
}
if (idx != songs.length - 1) return songs.at(idx + 1);
else return songs.at(0);
},
getPrevSong: function () {
var songs = this.get('songs');
var idx = songs.indexOf(songs.findWhere({ title: this.get('currentSong').get('title') }));
if (idx != 0) return songs.at(idx - 1);
else return songs.at(songs.length - 1);
},
// Get new songs from Billboard Chart
// First parse the top <numSongs> from the selected <genre>
// from Billboard, and then use YouTube gdata api to fetch
// the songs.
getNewSongs: function (callback, genre, numSongs) {
// FIXME: just trigger progress
var popupWindow = chrome.extension.getViews({ type: "popup" })[0];
if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(10);
var playlist = this;
playlist.get('songs').reset();
// Inspect Billboard Chart to find pop songs
$.get(url + numSongs + '/explicit=true/xml', function (data) {
var popupWindow = chrome.extension.getViews({ type: "popup" })[0];
if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(30);
var $feed = $(data).find('feed')
var $entries = $feed.find('entry')
var numAvailableSongs = $entries.length;
$entries.each(function (idx, entry) {
var title_artist_pair = $(entry).find('title')[0].innerHTML;
var title = $.trim(title_artist_pair.split(' - ')[0]);
var artist = $.trim(title_artist_pair.split(' - ')[1]);
var rank = idx + 1;
var query = title + " " + artist;
_searchYouTube(title, artist, rank, query, numAvailableSongs);
});
return;
});
function _searchYouTube(title, artist, rank, query, numAvailableSongs) {
var songs = playlist.get('songs');
$.ajax({
url: searchUrl,
type: "GET",
data: 'q=' + encodeURIComponent(query),
success: function (result) {
//console.log("\n**** 검색: "+query);
ajaxCount += 1;
if (result.items.length)
var videoId = result.items[0].id.videoId;
else
var videoId = null; // Cannot find the song on YouTube
var song = new Song({
title: title,
artist: artist,
rank: parseInt(rank),
query: query,
videoId: videoId
});
// Insert songs into the playlist in the order of their ranks
// *Note: Songs that do not exist on YouTube are ignored
if (videoId) songs.add(song, { silent: true });
// All the ajax calls are finished
if (ajaxCount == numAvailableSongs) {
var popupWindow = chrome.extension.getViews({ type: "popup" })[0];
if (popupWindow && popupWindow.popupView) popupWindow.popupView.setProgress(70);
songs.comparator = 'rank'
songs.sort();
// Remove useless playlsit methods
if (!playlist.get('currentSong')) {
playlist.set('currentSong', songs.at(0));
}
callback();
}
},
error: function (error) {
ajaxCount += 1;
if (ajaxCount == numAvailableSongs) {
var popupWindow = chrome.extension.getViews({ type: "popup" })[0];
if (popupWindow) popupWindow.popupView.setProgress(70);
if (!playlist.get('currentSong')) {
playlist.set('currentSong', songs.at(0));
}
callback();
}
} // end of error
}); // end of second ajax
} // end of _searchYouTube()
},
lookUpAndAddSingleSong: function (query) {
var playlist = this;
var youtubeAPIKey = "fdf";
var initialSearchURL = "df";
var searchUrl = initialSearchURL + "&key=" + youtubeAPIKey;
$.ajax({
url: searchUrl,
type: "GET",
data: 'q=' + encodeURIComponent(query),
success: function (result) {
if (result.items.length) {
var videoId = result.items[0].id.videoId;
var song = new Song({
title: result.items[0].snippet.title,
query: query,
videoId: videoId
});
} else var videoId = null; // Cannot find the song on YouTube
if (videoId) {
playlist.get('songs').add(song);
song.save(); // save to localStorage
}
}, error: function (xhr, status, errorThrown) {
var errorMessage = "lookUpAndAddSingleSong error: check http://instantmusicapp.com";
var popupWindow = chrome.extension.getViews({ type: "popup" })[0];
if (popupWindow && popupWindow.popupView) popupWindow.showErrorMessage(errorMessage);
return;
}
});
},
setMusicChart: function (chartName) {
// if the chart is provided, we pick from Melon, Billboard, iTunes
if (chartName) {
if (chartName == chrome.i18n.getMessage("melonChart"))
this.set('musicChart', AVAILABLE_CHARTS.melonChart);
else if (chartName == chrome.i18n.getMessage("billboardChart"))
this.set('musicChart', AVAILABLE_CHARTS.billboardChart);
else
this.set('musicChart', AVAILABLE_CHARTS.itunesChart);
// else, the user is looking for a personal favorite chart
} else {
this.set('musicChart', AVAILABLE_CHARTS.myChart);
}
}
});
return Playlist;
});

fuzzy search (fuse.js) using XML instead of JSON

Is it possible to use like fuse.js with an XML document instead of JSON? As it is now I only have an XML document with data and hope that I shouldn't make a new version as well for JSON.
Hope someone can help me out which direction I can/should go.
Kind regards,
Niels
Found the solution myself. Instead of the example with JSON placed on http://kiro.me/projects/fuse.html, here is the version with an XML call instead :)
$(function() {
function start(books) {
var $inputSearch = $('#hero-search'),
$results = $('#results ul'),
$authorCheckbox = $('#value'),
$titleCheckbox = $('#typeId'),
$caseCheckbox = $('#case'),
searchAuthors = true,
searchTitles = false,
isCaseSensitive = false,
fuse;
function search() {
$results.empty();
$.each(r, function(i, val) {
$resultShops.append('<li class="result-item"><span><img src="' + this.statusId + '" /></span> ' + this.value + '</li>');
});
}
function createFuse() {
var keys = [];
if (searchAuthors) {
keys.push('value');
}
if (searchTitles) {
keys.push('typeId');
}
fuse = new Fuse(books, {
keys: keys,
caseSensitive: isCaseSensitive
});
}
$inputSearch.on('keyup', search);
createFuse();
}
$.ajax({
type: 'GET',
dataType: 'xml',
url: 'xml-document/document.xml',
success: function(response) {
var suggestions = [];
$(response).find("searchResults").children().each(function(i, elm) {
var name = $(elm).find('name').text();
var url = $(elm).find('url').text();
var description = $(elm).find('description').text();
var statusId = $(elm).find('status').text();
var typeId = $(elm).find('type').text();
var result = {};
result.value = name;
result.url = url;
result.description = description;
result.statusId = statusId;
result.typeId = typeId;
suggestions.push(result);
});
start(suggestions);
},
error: function(response) {
console.log('failure',response);
}
});
});

Categories

Resources