RequestPager sends all the attributes in server_api to the request as query string. However, sometime I want to exclude a parameter on some condition. This is how, i'm setting the param:
server_api: {
query: function () {
return this.searchQuery
},
type: function(){ return this.searchType }
}
If this.searchQuery is empty, it makes the URL like ?query=&type=1. But I don't want to send query or type when it's empty or when my some other condition fails.
I know the dirty way like:
if(!myCollection.searchQuery){
delete(myCollection.server_api.licensed);
}
But this is not maintainable. Because text time I've to create this function. So, I'm looking for a better way of doing this. Any Help?
If you look at how server_api is used:
_.each(_.result(self, "server_api"), function(value, key){
if( _.isFunction(value) ) {
value = _.bind(value, self);
value = value();
}
queryAttributes[key] = value;
});
you'll see that it uses _.result:
result _.result(object, property)
If the value of the named property is a function then invoke it;
otherwise, return it.
var object = {cheese: 'crumpets', stuff: function(){ return 'nonsense'; }};
_.result(object, 'cheese');
=> "crumpets"
_.result(object, 'stuff');
=> "nonsense"
That means that you can make server_api a function which returns the appropriate object.
Related
I want to perform more logic before writing an element to an array:
tempDatensatz.push( () => {
var current = window.dataForDataTable[i].outbounds[key].updatedAt;
if (current) {
return current.toString();
} else {
return "".toString();
}
});
Getting the value from that array will be achieved like this:
tempDatensatz[0]()
But I want the same logic in it without having a function to call. I need a normal array, where I get a value like this:
tempDatensatz[0]
What can I do instead?
Updated
I published my project to gitHub, you can take a look if you need a better understanding :)
https://github.com/te2020/GoEuro/blob/master/GoEuro/Views/Home/Index.cshtml
Use an immediately invoked function instead of just a function:
tempDatensatz.push( (function(){
var current = window.dataForDataTable[i].outbounds[key].updatedAt;
if (current) {
return current.toString();
} else {
return "".toString();
}
})());
The function will be executed immediatly after it definition, returning the result. So push won't push a reference to that function but instead it will push it returned value (the result).
You can write a proxy as follows:
function makeProxy(array) {
return new Proxy(array, {
get(target, property) {
return !isNaN(property) ? target[property]() : target[property];
}
});
}
const tempDatensatz = [];
const useThisOne = makeProxy(tempDatensatz);
useThisOne.push(() => alert("Hi, Jane!"));
useThisOne[0];
Pushing/writing to the array will work as expected, but retrieving its elements will go through the get handler, which will execute the function.
You could just use an expression, like:
tempDatensatz.push(
(window.dataForDataTable[i].outbounds[key].updatedAt || '').toString();
);
For more complex expressions you can often use the ternary operator. For the above that would look like this:
tempDatensatz.push(
window.dataForDataTable[i].outbounds[key].updatedAt
? window.dataForDataTable[i].outbounds[key].updatedAt.toString()
: ''
);
Your code
When looking at the github code you linked to, you can do all that pushing with this "oneliner":
var tempDatensatz =
['companyId', 'mode', 'duration', 'outboundId', 'journeyId', 'departureTime',
'arrivalTime', 'stops', 'price', 'updatedAt', 'segments']
.map( prop => (window.dataForDataTable[i].outbounds[key][prop] || '').toString() );
I am trying to read a cookie in plain javascript only. I'm not using any jquery cookie library.
Here's how my cookie looks:
var task_cookie = {
task1 : getTask('task1')
, task2 : getTask('task2')
, task3: getTask('task3')
, task4: getTask('task4')
, task5: getTask('task5')
};
document.cookie = "task_cookie=" + JSON.stringify(task_cookie)+";path=/;domain=.task.com";
Now, I'm trying to read the value of task_cookie later on a different page
I found this code on stackoverflow
function read_cookie(name) {
var result = document.cookie.match(new RegExp(name + '=([^;]+)'));
result && (result = JSON.parse(result[1]));
return result;
}
But this would give me the whole task_cookie.I however want to grab each key value inside the task_cookie. I want something like this:
$.cookie('task1')
$.cookie('task2')
However this is very easy in jquery after I stringify. But forsome reason I need to use pure javascript. How can I get individual values of task1 , task2 etc which are inside the task_cookie object? I'm having a hard time figuring this out :/
The function is returning the entire object, so you can just select an individual cookie from the function:
read_cookie('task_cookie')['task1'];
Or something similar. The above will just return the task1, but you can iterate through all the tasks.
Better yet, you can make the read_cookie function an object method and just return the cookie object to a property of the parent object.
var cookieHandler = {
get: function(name) {
//code to get cookies
//push to cookies array
},
cookies: []
};
That way you don't have to create a bunch of instances for a global function every time you iterate over a task.
So read the value from the cookie after you get the object.
function read_cookie(name) {
var result = document.cookie.match(new RegExp('tasj_cookie=([^;]+)'));
result && (result = JSON.parse(result[1]));
return result ? result[name] : null;
}
Better yet, use localstorage and not cookies.
localstorage.setItem("task1", getTask('task1'));
function read_storage (name) {
return localstorage.getItem(name); //might need to use JSON.parse() depending on the data
}
console.log(read_storage("task1"));
I have been trying to execute a function as follows, but am not succeeding.
var leagueSelect = "allLeagues";
loadTable("#loadLeaguesTable","php/leagueTable.php",'leagueSelect',leagueSelect);
The loadTable function:
function loadTable(tableDiv, tableURL, tableType, tableVal){
$.post(tableURL,{tableType:tableVal},function(data){
$(tableDiv).append(data);
});
}
I'm trying to send the values in the post in this format: { leagueSelect: leagueSelect }.
If I hard-code leagueSelect into my function in place of the tableType parameter in the $.post function, it works.
How am I supposed to send 'leagueSelect' properly in my function call?
I'm thinking the data[key] = value method but I didn't get that working either.
Thanks.
When you assign the variable you're actually creating a new object with the property tableType set to whatever the tableVal value is.
Instead you need to use the object[key] = val; syntax or pass the post data in directly like this:
var leagueSelect = "allLeagues";
loadTable("#loadLeaguesTable", "php/leagueTable.php", { leagueSelect: leagueSelect });
function loadTable(tableDiv, tableURL, postData) {
$.post(tableURL, postData, function(data) {
$(tableDiv).append(data);
});
}
I want to be able to provide a JavaScript function that will be called whenever any property of a specified object is being queried or updated. Is that possible, if so, how?
To give a simple example, if I have obj = { a:3 }, I want to have some function called whenever any code queries obj.a, and be able to return whatever I want instead of its current value, e.g. 4 instead of 3.
It's easy, you can use Object.prototype.defineProperty. more on it here.
To answer your question:
var obj = {};
Object.defineProperty(obj, "a", {
get: function() {console.log("I've been accessed"); return 5;//or whatever value}
});
console.log(obj.a)
Working fiddle
Update
The above can be shorthanded.
Object.prototype.addMonitoredGetter = function(property, value, callback) {
Object.defineProperty(this, property, {
writable: false,
get: function() {callback(); return this[property]
};
};
And the callback here could be the monitoring function. Of course, needs default params and checks, but it should do the trick.
There's a watch method available for Firefox...
o.watch("p", function(...)
http://jsfiddle.net/NTc52/
I have run into some trouble with a piece of backbone code. The code below relates to a render function. I can retrieve all the models. My trouble arises when I try to use the "Collections.where" method at line marked number #1. As you can see, I have passed an object literal into the render function but for some reason I am unable to reference it within the customers.where method on line #1. When I give this method a literal number like 45 it works. Is there some way around this so I can pass the variable reference in?
Thanks alot
render: function(options) {
var that = this;
if (options.id) {
var customers = new Customers();
customers.fetch({
success: function (customers) {
/* #1 --> */ var musketeers = customers.where({musketeerId: options.id});
console.log(musketeers.length) //doesn't work as options.id is failing on last line
var template = _.template($('#customer-list-template').html(), {
customers: customers.models
});
that.$el.html(template);
console.log(customers.models);
}
});
} else {
var template = _.template($('#customer-list-template').html(), {});
that.$el.html(template);
}
}
Although it isn't explicitly documented, Collection#where uses strict equality (===) when searching. From the fine source code:
where: function(attrs, first) {
if (_.isEmpty(attrs)) return first ? void 0 : [];
return this[first ? 'find' : 'filter'](function(model) {
for (var key in attrs) {
if (attrs[key] !== model.get(key)) return false;
}
return true;
});
},
note the attrs[key] !== model.get(key) inside the callback function, that won't consider 10 (a probable id value) and '10' (a probable search value extracted from an <input>) to be a match. That means that:
customers.where({musketeerId: 10});
might find something whereas:
customers.where({musketeerId: '10'});
won't.
You can get around this sort of thing with parseInt:
// Way off where you extract values from the `<input>`...
options.id = parseInt($input.val(), 10);