Retrieving elements from an array using events in Meteor - javascript

I am getting [object, object] instead the elements from the array in the 'categories' function. Though I am not sure, perhaps this is expected and I am just getting it wrong.
if (Meteor.isClient) {
Template.ipsosboard.helpers({
'categories': function() {
return array; // Some data stored as JS Object in lib.
},
'currentElement': function() {
return Session.get('selectedEvent');
}
});
Template.ipsosboard.events({
"change #category-select": function(event, template) {
var selectedEvent = $(event.currentTarget).val();
Session.set('selectedEvent', selectedEvent);
console.log("EventNum: " + selectedEvent);
}
});
}; //end of client code.
if (Meteor.isServer) {
//code to run by server here.
};

This seems to fix it. It needed to convert the object into an array. Note: the 'data' is a json file stored as a JS object in lib folder of the project, thus I needed to convert it.
if (Meteor.isClient) {
Template.ipsosboard.helpers({
'categories': function() {
It needed to be converted to array using the function below.
var myObj = data;
var array = $.map(myObj, function(value, index) {
return value;
});
return array;
},
So now it returns the data as required.
'currentElement': function() {
return Session.get('selectedEvent');
}
});
Template.ipsosboard.events({
"change #category-select": function(event, template) {
var selectedEvent = $(event.currentTarget).val();
Session.set('selectedEvent', selectedEvent);
console.log("EventNum: " + selectedEvent);
}
});
}; //end of client code.
if (Meteor.isServer) {
//code to run by server here.
};

Related

Access function in module with similar name of function in another module

Code:
for (var i in RESTCalls_GET) {
describe('Retrieve all Product Component names and their IDs', function() {
var restCalls;
beforeEach(function() {
RESTCalls_GET.setClient(mockClient);
restCalls = new Rest_calls(mockClient);
});
describe(i + '()', function() {
it('should return data if response code is 200', function(done) {
mockClient.mockURLForSucceed(eval('restCalls.' + i + "_RESTCall"), eval('RESTCalls_GET_ExampleData.' + i + "_ExampleData"), 200);
eval('RESTCalls_GET.' + i)(function(result) {
result.should.equal(eval('RESTCalls_GET_ExampleData.' + i + "_ExampleData"));
done();
});
}),
it('should return error if response code is NOT 200', function(done) {
mockClient.mockURLForError(eval('restCalls.' + i + "_RESTCall"), null, TestData.RESTCallResponseError_Test);
eval('RESTCalls_GET.' + i)(function(errorObj) {
errorObj.should.have.property('errorCode');
done();
});
});
});
});
}
I am looping though functions in RESTCalls_GET. Say, for example, i = getComponent, a function called getComponent_RESTCall will be in module restCalls
I have been told that one way to accomplish this is by using eval() (even though it is not recommended). This way is not working and when I debug, the parameters which use eval() in mockURLForSucceed are undefined.
This obviously causes all my tests to fail.
Any suggestions appreciated.
EDIT: (additional information)
var mockClient = function() {
var urlMap = {};
return {
get: function(url, callback) {
var entry = urlMap[url];
if (entry) {
callback(entry[0], entry[1]);
} else {
console.error("Unable to match URL " + url);
}
return {
on: function() {
//Ignore
}
};
},
mockURLForSucceed: function(URLofRESTCall, succeedData, succeedRes) {
urlMap[URLofRESTCall] = [succeedData, {statusCode: succeedRes}];
},
mockURLForError: function(URLofRESTCall, errorData, errorRes) {
urlMap[URLofRESTCall] = [errorData, errorRes];
}
}
}();
EDIT: (half way there)
I've resorted back to eval() an got the function/variable name required in format file.functionName by this:
var RESTCallURL = eval('"restCalls." + i + "_RESTCall"');
var RESTCallData = eval('"RESTCalls_GET_ExampleData." + i + "_ExampleData"');
The problem I'm having now if that these are strings. So when I pass them into a function, it gets that string value and not the one it equals in it's own function, does that make sense?
What I mean is that if I passed in RESTCallURL into a function now, then the value of that parameter would be restCalls.whatever_RESTCall whereas before it got the URL of the REST Call I am calling (http://whatever). Since I now have the name of the function, am I able to search for functions in my project by that name?
This task seems so simple to do and I think I am over thinking it.
I don't think you need eval there, what about using
RESTCalls_GET[i](function(result) {
result.should.equal(RESTCalls_GET_ExampleData[i + '_ExampleData']));
done();
});
You could easily test this behaviour by defining the following in your browser console
var test = {
'some-function': function() { console.log('works'); }
};
test['some-function']();

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();
}
}

Angularjs polling API to check for empty array in JSON

Im trying to create a service that polls an API and checks to see if the response has an empty arrary. If it does, I want it to keep checking every second until the array from the response is filled. For instace if the array is empty the JSON will return:
{
choices: [ ]
}
To set this up I've created the service like so. The issue is that data.response.choices.length seems to be undefined and I'm not exacly sure how to check for the array being empty. The rest of the code seems to work fine. Ideas?
angular.module('help')
.factory('Poller', function($http, $timeout) {
var data = { response: {}, calls: 0 };
var poller = function() {
if (data.response.choices.length === 0) {
$http.get('menu.json').then(function(r) {
data.response = r.data;
data.calls++;
$timeout(poller, 1000);
});
console.log('success');
} else {
$http.get('menu.json').then(function(r) {
data.response = r.data;
});
console.log('damnit');
}
};
poller();
return {
data: data
};
});
data.response is set to an empty object, so the first time poller is called, data.response.choices is guaranteed to be undefined.
I think the code can be simplified to this...
angular.module('help')
.factory('Poller', function($http, $timeout) {
var data = { response: {}, calls: 0 };
var poller = function() {
$http.get('menu.json').then(function(r) {
data.response = r.data;
data.calls++;
if (r.data.choices.length === 0) {
$timeout(poller, 1000);
}
});
};
poller();
return {
data: data
};
});
You can use this:
<!-- Image Gallery -->
<div class="gallery" ng-show="product.images.length">

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();

Meteor call template method from another method

I want to call a method within a method for clientside but I don't know how to handle it, i've tried by calling like myFunction()and this.myFunction() but it is not working... This is my code
Template.decision.rendered = function () {
if ($(".active").length == 0) {
var random = Math.floor(Math.random() * 1000);
var $items = $(".item");
$items.eq(random % $items.length).addClass("active");
}
$.each($(".item"), function (index, value) {
if (Session.get($(this).attr('id'))) {
this.showResults(value.option);
}
});
};
Template.decision.showResults = function($option) {
$('#result').html('Option ' + $option + ' is voted');
};
As you can see I want to call showResults for each item inside rendered callback...
Found it using Template.decision.showResults(); silly me.
I think that a better way depending on what you are trying to do would be either to use a Session variable or a Meteor Method:
Session Variable.
Template.decision.created = function() {
Session.setDefault('showResults', false);
}
Template.decision.rendered = function() {
// [...]
$.each($(".item"), function (index, value) {
if (Session.get($(this).attr('id'))) {
Session.set('showResults', true);
}
});
}
Template.decision.showResults = function() {
return Session.get('showResults');
}
// in your template
<template name="decision">
{{#if showResults}}
<p>Here is the results.</p>
{{/if}}
</template>
Meteor Method.
// On the client.
Template.decision.rendered = function() {
// [...]
$.each($(".item"), function (index, value) {
if (Session.get($(this).attr('id'))) {
Meteor.call('showResults', function(error, result) {
if (!error and result === true) {
$('.class').hide() // It is here that you modify the DOM element according to the server response and your needs.
}
});
}
});
}
// Server-side method
// But, if you want it to react like a stub, put it inside your lib folder.
Meteor.methods({
showResults: function() {
// do your thing
result = true; // let's say everything works as expected on server-side, we return true
return result;
}
});

Categories

Resources