Access variable from another JS file - javascript

I have two JS files, base_player.js and station.js.
I have some logic in base_player.js that needs access to a value that comes from station.js. While the var is 'global', it is wrapped in a namepace mm.Station. The value I need is a UUID of a selected station:
mm.Station = function($el) {
"use strict";
if (_.isUndefined($el)) {
return;
}
var self = mm.EventEmitter();
var $actions;
self.uuid = $el.attr("data-uuid");
.........
I feed any selected station with songs in batches at a certain point in a queue. This logic all happens in base_player.js.
I want to get the UUID from station.js to use in this GET in base_player.js:
mm.BasePlayer = function ($el) {
........
function feedSelectedStation(uuid) {
if(_.isUndefined(uuid)){
return false;
}
$.get('/feed-station/' + uuid)
.done(function (data) {
console.log('feedSelectedStation');
if(!_.has(data, "list")){ return; }
self.queue = self.queue.concat(data.list);
});
}
.........
I don't write much Javascript so I'm a bit unsure how to achieve this. Any pointers appreciated.

Related

Set factory variable from state

I am using factories to get feed data for different categories in wordpress using the Rest-API and I am wondering if I am making a complete mess of it.
I have around 13 different categories that I am making just a basic call to that look like this:
.factory('Articles1', function ($http) {
var articles1 = [];
storageKey = "articles1";
function _getCache() {
var cache = localStorage.getItem(storageKey );
if (cache)
articles = angular.fromJson(cache);
}
return {
all: function () {
return $http.get("http://www.example.com/wp-json/posts?filter[category_name]=category1").then(function (response) {
articles1 = response.data;
console.log(response.data);
return articles1;
});
},
get: function (articleId) {
if (!articles1.length)
_getCache();
for (var i = 0; i < articles1.length; i++) {
if (parseInt(articles1[i].ID) === parseInt(article1Id)) {
return articles1[i];
}
}
return null;
}
}
})
there is a separate call for each of the 13 categories to get articles.
Is there a way to set the [category_name] to a variable, possibly the state name or something to that I can just make 1 call to wordpress and the url will rely on what state the user has chosen? I have been trying to learn angular and from what I have seen I am sure there must be a more elegant way of doing something like this?
Inject the Angular $location provider and you will have access to every part of your current URL (you can also use it to listen to the state changes). Then just build the URL to Wordpress dynamically:
.factory('Articles1', function ($http, $location) {
// ...
return {
all: function () {
var currentCategory = $location.path().split('/')[1]; // Assuming the category is part of the path and at the second place
var wpUrl = 'http://www.example.com/wp-json/posts?filter[category_name]=' + currentCategory;
return $http.get(wpUrl).then(function (response) { // ...

How to know all JSON object has been iterated? [duplicate]

This question already has answers here:
Wait until all jQuery Ajax requests are done?
(22 answers)
Closed 7 years ago.
I m working on phonegap product using jquery and jquery mobile, the scenario is, when user is logging in for first time, we sync all the data and after done we forward user to another view. The items are retrieved in json format from server. Here are the portion of my code. I have called the webservice and the response is returned as JSON objects in response variable.
$(response.data.module.registration).each(function(k,v){
//insert into app's sqlite database
});
$(response.data.module.attendance).each(function(k,v){
//insert into app's sqlite database
});
$(response.data.items.grocery).each(function(k,v){
//insert into app's sqlite database
});
//and so on. There could be many rows in each loop above.
My question is how to know all rows has been inserted from the loop so that I can forward user to restricted area.
more precisely, how to know all JSON object has been iterated successfully?
What i tried is put counter in each loop and check if sum of all the counters is equal to total items we are iterating. But this didn't work the sum of all the counters are readily available before all items are inserted.
EDIT
Here is my helper function that inserts record into sqlite db. This didn't work, user was logged in before all data are inserted. Can you tell me where I went wrong
var sqlhelper = {
insertJSONData:function(tablename,data,callback){
var dfrd = $.Deferred();
var fields=sqlhelper.separateFieldData(data,"field");
var dataval=sqlhelper.separateFieldData(data,"value");
sqlhelper.db.transaction(function(tx) {
var sqlquery='INSERT INTO '+tablename+' ('+fields+') values('+dataval+')';
console.log(sqlquery);
tx.executeSql(sqlquery,[],function(tx,result){
dfrd.resolve(result);
console.log('Success');
},sqlhelper.errorCB);
if(callback!=undefined){
callback();
}
});
return dfrd.promise();
}
}
And here is the code that fetches server response
function defObj1()
{
if(typeof response.data.module.registration!="undefined"){
$(response.data.module.registration).each(function(i,e){
var data = {
'reg_id': e.reg_id,
'reg_name': e.reg_name,
'reg_desc': e.reg_desc,
'reg_status': e.reg_status
};
sqlhelper.insertJSONData('tbl_registration',data);
}); // end of each loop
}
}
function defObj2()
{
if(typeof response.data.items.grocery!="undefined"){
$(response.data.items.grocery).each(function(i,e){
var data = {
'grocery_id': e.grocery_id,
'item_name': e.item_name,
'item_qty': e.item_qty,
'item_unit_price': e.item_unit_price
};
sqlhelper.insertJSONData('tbl_grocery',data);
}); // end of each loop
}
}
$.when(defObj1() ,defObj2()).done(function(a1,a2){
//sync complete so login user
doLogin();
})
Thanks
try this. (Edited)
var isValid = true, i = 0, sum, callback = function () {
//if all inserting is successfully it is called
};
...
$(response.data.module.registration).each(function (k, v) {
//insert into app's sqlite database
var data = {
'reg_id': e.reg_id,
'reg_name': e.reg_name,
'reg_desc': e.reg_desc,
'reg_status': e.reg_status
};
sqlhelper.insertJSONData('tbl_registration', data, function (data) {
if (!data) {
isValid = false;
sum++;
}
i++;//onSuccess function
checkLast(i);//call this lastly method or each
}, function () {
i++;//onError function
});
});
...
//other codes is identical logic
...
function checkLast(i) {
if (i == sum) {
callback();
}
}
...
I have added successCallbak and errorCallback to your sqlhelper
var sqlhelper = {
insertJSONData: function (tablename, data, successCallbak, errorCallback) {
var dfrd = $.Deferred();
var fields = sqlhelper.separateFieldData(data, "field");
var dataval = sqlhelper.separateFieldData(data, "value");
sqlhelper.db.transaction(function (tx) {
var sqlquery = 'INSERT INTO ' + tablename + ' (' + fields + ') values(' + dataval + ')';
console.log(sqlquery);
tx.executeSql(sqlquery, [], function (tx, result) {
dfrd.resolve(result);
if (successCallback) {
successCallback(result);
}
console.log('Success');
}, sqlhelper.errorCB);
if (errorCallback) {
errorCallback();
}
});
return dfrd.promise();
}
}

Knockout Check If Existing in observableArray before Push

I am new to Knockout and I have a little problem stopping me from completing my simple project.I have an observableArray called loanDeductions that I display in a table with foreach binding. I have another observableArray called loanDeductionsList which is also from the json data of my first observableArray, I used it in my drop down list which when a value is selected, it will push the selected data to my table. If it didn't make sense as I cannot really explain it clearly, this is my javascript file:
var deductionLine = function (deductionID, deductionName, amount) {
self = this;
self.deductionID = ko.observable(deductionID);
self.deductionName = ko.observable(deductionName);
self.amount = ko.observable(formatCurrency(amount));
};
function LoanDeductions(deductions) {
var self = this;
self.loanDeductions = ko.observableArray(ko.utils.arrayMap(deductions, function (deduction) {
return new deductionLine(deduction.deductionID, deduction.deductionName, deduction.amount)
}));
self.loanDeductionsList = ko.observableArray(ko.utils.arrayMap(deductions, function (deduction) {
return new deductionLine(deduction.deductionID, deduction.deductionName, deduction.amount)
}));
self.selectedDeduction = ko.observable();
self.selectedDeduction.subscribe(function (data) {
self.loanDeductions.push({
deductionID: data.deductionID,
deductionName: data.deductionName,
amount: data.amount,
});
});
}
Can you help me find a way to make my function selectedDeduction.subscribe() push the data ONLY when the item to be pushed is not existing in my loanDeductions observableArray.
Any help will be greatly appreciated. Thank you!
I am somewhat aware that the way I populate my dropdown list may o may not be the best way to do it, I am open to suggestion of a better way and rewrite my program.
just to share what I did I added this line in my selectedDeduction.subscribe():
self.selectedDeduction.subscribe(function (data) {
var match = ko.utils.arrayFirst(self.loanDeductions(), function(deduction) {
return deduction.deductionID() === data.deductionID();
});
if (match) {
alert(data.deductionName() + ' already exists!');
} else {
self.loanDeductions.push({
deductionID: data.deductionID,
deductionName: data.deductionName,
amount: data.amount,
});
}
});

Replace attributes of a document in publish function

I'm using meteor and I have a question about the publish function (server side)
Meteor.publish('users', function () { .... }
I'm sending now documents to the browser which have id's of other collections. For example the Task document belongs to a project
{
title: '....',
projectId: 'KjbJHvJCHTCJGVY234',
...
}
What I want is to add a property to the this document projectTitle so I don't have to look up the project on the client. However, when I add this property in the publish function it is not send to the client. This is what I've tried:
Meteor.publish('tasks', function () {
var tasks = Tasks.find();
tasks.forEach(function (task) {
var project = Projects.findOne({_id: task.projectId});
task.projectTitle = project.title;
});
return tasks;
}
Any suggestions how to modify documents (not persistent) inside the publish function?
You could do this:
Meteor.publish("tasks", function() {
var transform = function(task) {
var project = Projects.findOne({_id: task.projectId});
task.projectTitle = project.title;
return task;
}
var self = this;
var tasks = Tasks.find().observe({
added: function (document) {
self.added('tasks', document._id, transform(document));
},
changed: function (newDocument, oldDocument) {
self.changed('tasks', document._id, transform(newDocument));
},
removed: function (oldDocument) {
self.removed('tasks', oldDocument._id);
}
});
self.ready();
self.onStop(function () {
tasks.stop();
});
});
There's a lot of custom logic there, but the 'transform' basically adds the attributes in.
Your code looks good but you're forgetting the .fetch() method on your task request. It should be var tasks = Tasks.find().fetch();

jquery my done callback gets only called one time i dont get why

/**
* Downloads the fingerprint preview data
*/
this.fetchFingerprintPreviews = function (url) {
var that = this;
var dfd = jQuery.Deferred();
jQuery.get(url)
.done(function (resp) {
var linkNodes = conn.getLinksViaRelation(resp,
'http://ws.bdr.de/webhd/hdcap/rels/finger-preview/');
jQuery(linkNodes).each(function () {
var link = jQuery(this);
var fpIndex = link.prev("index, bdr\\:index").html();
var fpType = link.attr('type');
jQuery.get(link.attr('href'), {"encoding":"base64"}, null, "text")
.done(function (imageDataBase64) {
fingerprintPreview[fpIndex] = {};
fingerprintPreview[fpIndex].imageData = imageDataBase64;
fingerprintPreview[fpIndex].type = fpType;
console.log(fingerprintPreview);
if (Object.keys(fingerprintPreview).length ==
Object.keys(linkNodes).length) {
dfd.resolve();
}
});
});
});
return dfd;
}
a new version added which makes use of lexical local variables. still not working.
m a bit lost at the moment...
also added a log statement which gets called only one time.
i would expect the log to get called two times.
any ideas?
The problem isn't that your done callback is called once, but that you change the same fingerprintPreview each time it is called because that has the value of end of loop when the callbaks are called.
The solution is to not reuse this externally declared variable but a new one, declared in the function you give to each :
jQuery(linkNodes).each(function () {
var link = jQuery(this);
var fpIndex = link.prev("index, bdr\\:index").html();
var fpType = link.attr('type');
jQuery.get(link.attr('href'), {"encoding":"base64"}, null, "text")
.done(function (imageDataBase64) {
fingerprintPreview[fpIndex] = {};
fingerprintPreview[fpIndex].imageData = imageDataBase64;
fingerprintPreview[fpIndex].type = fpType;
if (Object.keys(fingerprintPreview).length == Object.keys(linkNodes).length) {
alert("foo");
}
});
});
i found out what the problem was. dystroys answer is correct but was not adressing my original problem. so the thing is that when i have a firebug breakpoint in my done function callback it will be called only one time. so having breakpoints set with firebug can lead to uninterpreted js code... ffs!

Categories

Resources