Delete cascade JayData - javascript

Following my previous question here, is there a way to have the same behaviour as ON DELETE CASCADE (MySQL) with JayData?
If I delete a Test I would like all linked Chapters and Checks to be deleted. I tried this code:
myDB.onReady(function(){
myDB.Tests.filter(function(test) { return test.Name == this.Name; }, {Name: myTest.Name}).forEach(function(test){
console.log('Starting to remove '+test.Name);
myDB.Tests.remove(test);
myDB.saveChanges(function() {
console.log(test.Name+' removed');
});
});
});
But it doesn't delete the children. Could it be linked with the declaration of Chapters and Checks in the context? JayData probably doesn't see them as children but as independent entities.
I've also seen somewhere that there is some configuration required to do cascading operations with SQLite. I guessed JayData would deal with that.

There is no such functionality in JayData. WebSQL/sqlite has this function built-in but indexedDb hasn't. We could implement it in indexedDb but nobody has asked for it. If you need it then please either add it to our backlog or create an issue on github.

Related

Counting files with metadata in a GridFS

I've been trying to implement a feature into a website that displays the number of unread files in a GridFS. Each file, when stored, is defined with the metadata completed: "false". In the following helper function, I try to find the number of files that are still labeled with this data.
incomplete_diagnostics_count: function() {
return Diagnostics.find({metadata: {completed: "false"}}).count();
},
As of now, this code doesn't work. How would I go about fixing this?
There wasn't a distinct answer anywhere on the internet, but apparently it was just a syntax error:
incomplete_diagnostics_count: function() {
return Diagnostics.find({},{metadata: {completed: "false"}}).count();
},
The extra bracket in the find() dependents fixed it.

Inifinite loop when using Meteor.call inside helper

I spent so much time on my meteor app, and now that users are coming in, it's so slow! Almost unusable, specially on mobile.
I am having to revamp all my code and try to pass all logic to the server so the client is not so overloaded.
However, I am running into many issues. I've tried all sort of solutions but nothing is working.
Anyways, here is the issue at hand. When I try to use server side methods, an infinite loop gets triggered that will console.log on the server thousands of times.
Here is the code
on templates/question.js
Template.questionItem.helpers({
editPermission: function(){
var question = this
Meteor.call('checkForEditPermission', question, function(error, result){
console.log(result)
Session.set('editPermissionVar', result)
});
return Session.get('editPermissionVar')
}
});
on server/question.js
if (Meteor.isServer) {
Meteor.startup(function() {
Meteor.methods({
checkForEditPermission: function(question) {
if (Meteor.user() && (question.user_id == Meteor.userId())) {
return true
}
}
});
});
}
This is a very simple helper. I have dozens of other, more complex helpers, but I can't figure out how to put them server side. I was taught to do things on the client, never realizing I was overloading it.
Not sure if this helps, but what I had before (the client only helper) is much simpler:
editPermission: function(){
if (currentUser && (this.user_id == currentUser._id)) {
return true
}
}
Doesn't need meteor.call.
The question is, how do you deal with calling methods from client and using them as helpers. I have tried many things, like reactive vars and session variables, but nothing seems to work. I know this particular example is very simple, and wouldn't take much computation, but I think the principle is the same with more complex helpers. The question is how to move them to the server.
Thanks
The question is, how do you deal with calling methods
How I deal is Meteor.call wich makes changes in database and just displaying data with cursors.
So for example as you have some template like:
Template.exammple.events({'click .sth' : function(event){
Meteor.call("serveside", {some: data});
return false;
});
In 'serverside' I got all callculations or DB queries/inserts/updates etc
and helper:
Template.example.helpers({
example : function(){
return dbCollectionName.find();
});
In this way I do not need to use Meteor.call for pulling data/results. Mostly I save results in its raw shape and just addjusting diplaying after pulling them from with cursor.
MongoDB works perfect with meteor, and if you need some aggregation you can use this extension: Meteor Aggregate

Using PHP/JS to perform actions

to help teach myself PHP I've tasked myself with updating old mysql_* code with PDO.
This has been going great, and as I've been learning I've been able to greatly reduce the amount of code. However my research has ran into a brick wall in a particular area.
Currently, we have it so projects are recorded in a list view, with a set of 'actions/options' for each project. Each of these actions links to a PHP file which runs a small amount of code then sends you back to the list view.
Here is an example:
function projectComplete(id) {
location.href = "complete.php?id=" + id;
}
<button type="button" class="projectComplete" onclick="projectComplete('<?= htmlentities($row['projectid']); ?>')"></button>
The complete.php file simply contains an SQL update query that sets a column in the record a completed state of '1'.
I originally wanted to ask the question 'what is the best practice for handling this type of interaction' however that may attract opinion based answers which I read is not allowed here.
Instead I will phrase it like this: Is there a way of having all of these 'actions' run in the same page? (ideally able to use buttons rather than forms, due to difficulty in layout styling of forms)
I know that if it used forms, I could simply name each form's submit button differently then run an if statement (the only issue would be passing the id, but I'm sure I could figure that out e.g.
if (isset($_POST['exampleAction'])) { Run the code.. }
Any links to guides/tutorials/similar questions etc would be very much appreciated. As previously stated, I'm self-learning PHP - I know very few 'best practices' and would like to learn more.
One thing you could consider is an MVC pattern, where a page call will run some function based on some parameters. A full-blown MVC framework is probably more than you need for this project, but mimicking the controller dispatching is certainly doable. Something to this effect could work (code untested):
if (isset($_GET['action'])) {
new Actions()->dispatch('action_'.$_GET['action']);
}
class Actions {
public function dispatch($action) {
if (method_exists($this, $action)) {
$this->$action($_GET);
} else {
http_response_code(400);
exit(1);
}
}
// The following functions are examples only!
public function action_Create($parameters) {
// Create database record
}
public function action_Read($parameters) {
// Read database record
}
public function action_Update($parameters) {
// Update database record
}
public function action_Delete($parameters) {
// Delete database record
}
}
Then you'd call (for example) action.php?action=Read&name=foo&author=bar

A JavaScript concatenator to help data hiding under modularization?

I previously run into the problems of data hiding under modularization in JavaScript. Please see the links below:
Module pattern- How to split the code for one module into different js files?
JavaScript - extract out function while keeping it private
To illustrate the problem, see the example below. My goal is to split my long js file into 2 files, but some functions need to access some private variables:
first.js:
(function(context) {
var parentPrivate = 'parentPrivate';
})(window.myGlobalNamespace);
second.js:
(function(context) {
this.childFunction = console.log('trying to access parent private field: ' + parentPriavte);
}(window.myGlobalNamespace.subNamspace);
Now this wouldn't work because child doesn't have access to parent. One solution is to make parentPrivate publicly visible, but that is unacceptable in my case.
Quoting #Louis who gave an answer for one of the previous questions:
"We can't have a field that's accessible by child but not to outside
public (i.e. protected). Is there any way to achieve that?"
If you want modularization (i.e. you want the child to be coded
separately from the parent), I do not believe this is possible in
JavaScript. It would be possible to have child and parent operate in
the same closure but then this would not be modular. This is true with
or without RequireJS.
The problem is that the parent and the child are not inside the same closure. Therefore I'm thinking, does it make sense to create a library that puts files into the same closure?
Something like:
concatenator.putIntoOneClosure(["public/js/first.js", "public/js/second.js"]);
Of course we can take in more arguments to specify namespaces etc. Note that it is not the same functionality we get from RequireJS. RequireJS achieves modularization while this concatenator focuses on data hiding under the condition of modularization.
So does any of the above make sense? Or am I missing out some important points? Any thoughts are welcomed.
If you need things available in two separate files, then you can't have true privacy... however, something similar to this may work for you:
first.js:
(function(context) {
var sharedProperties = {
sharedProp1: "This is shared"
};
function alertSharedProp1() {
alert (sharedProperties.sharedProp1)
}
window[context] = {
sharedProperties: sharedProperties,
alertSharedProp1: alertSharedProp1
};
})("myGlobalNamespace");
second.js:
(function(parent, context) {
// CHANGED: `this` doesn't do what you think it does here.
var childFunction = function() {
console.log('trying to access parent private field: ' + window.myGlobalNamespace.sharedProperties.sharedProp1);
};
window[parent][context] = {
childFunction: childFunction
};
}("myGlobalNamespace", "subNamspace"));
window.myGlobalNamespace.subNamspace.childFunction();
Edit detailed answer based on comments
What I did was to set up a source file that looked like this:
master.js
(function() {
##include: file1.js##
##include: file2.js##
}());
Then I wrote a script (in windows scripting, in my case) that read in master.js and then read through line by line looking for the ##include: filename.js## lines. When it found such a line it read in the include file and just dumped it out.
My particular needs were special since I was writing a browser plugin that needed to work in three different browsers and had to be wrapped up separately, yet for my own sanity I wanted separate files to work with.

Is saving elements as object properties good practice?

I'm writing a small JavaScript framework for fun and possible implementation similar to backbone(hence the tag). I've started saving elements as object properties, as shown below. I'm not sure if I've seen this done, so I was curious if this causes any issues.
Similarly, If the module depends on other modules I list those at the top of the object in the form of....another object.
I wanted a way to list dependencies ( page elements or JavaScript modules ) and detect any issues up front. This has similar ( not same ) benefits as dependency injection.
This is a specific question on this code review post which explains a bit further on how the framework works.
/*MUserTry
**
**
**
*/
$A.modelAjax({
Name: 'MUserTry',
S: {
DynSma: SDynSma,
DynTwe: SDynTwe,
DynArc: SDynArc,
AniFlipPage: SAniFlipPage,
ClientStorage: SClientStorage
},
E: {
but: $A('#ut_but')[0]
},
J: {
box: $('#ut_box')
},
init: function () {
var pipe = {},
this_hold = this;
this.J.box.draggable();
this.E.but.addEventListener("click", function () {
pipe = $A.definePipe(this_hold.Name);
$A.ajaxMachine(pipe);
}, false);
},
pre: function (pipe) {
pipe.page.email = this.e_button.getAttribute('data-email');
pipe.proceed = true;
},
post: function (pipe) {
this.S.ClientStorage.setAll(pipe.server.smalls);
this.S.DynSma.run(pipe.server.smalls);
this.S.DynArc.run(pipe.server.arcmarks);
this.S.DynTwe.run(pipe.server.tweets);
this.S.AniFlipPage.run('ma');
},
finish: function (pipe) {
$A.log(pipe);
}
});
Ok first off let me offer the obligatory "you'll never get a better wheel by re-inventing the wheel" warning. Whatever you're trying to accomplish, you're almost certainly going to be more successful with it if you use an existing library. And even if there is good cause for you to make your own, it would still benefit you immensely to at least look at existing libraries.
But ... maybe you're just having fun with this project, and looking at other projects isn't fun so you're not doing it. Fair enough.
In any case, if you do look at Backbone, you'll find that this practice is core to the Backbone View class. Every View in Backbone has an "el" and "$el" property, which refer to the raw DOM element for the view and the jQuery-wrapped version of that element.
Backbone has no real performance issues with this because variables/properties in JS are just pointers; in other words, when you set the property of an object to an element, you aren't duplicating that element, you're just adding a reference to it (to put it another way, it's more like you're an A tag rather than a whole new document).
The one time Backbone does have a problem though (and your framework will too) is with stale references. In other words, if you just remove element X from the page, the browser will stop using memory for it (eventually, via garbage collection). But if there is an object out there which points to that element, it won't get garbage-collected, because anything with a reference isn't "garbage".
So, the main thing you have to watch out for is making sure that these objects either:
A) get deleted whenever their elements do, or
B) get rid of their references (eg. delete obj.reference) when their elements get deleted
If you don't do that, things will still probably work just fine ... until you use it on a page with lots of elements being created/deleted, at which point Firefox will start popping up "this script took way too long to run, are you really sure you want to be doing this?" messages.

Categories