Could this be a good use of global variables? - ajax

Global state is conventionally frowned upon. However, I think I can use it clientside to make my app simpler.
I have an AJAX web app that sets up several values when the user logs in - user id, as well as some other information. This info does not change for the lifetime of the app.
I also have a cache of data to minimize trips to the server.
Can I safely make all these global? (the read-only user info and the cache) I think it would make it simpler because then I wouldn't have to worry about passing the values off between functions in sometimes awkward ways.
Essentially, it'd be like constants whose values aren't known at "compile-time."
In some ways, the DOM itself serves as a form of global state - I could store a value in HTML and it would be accessible from anywhere in the program.

There's nothing wrong in using globals, if you know what you're doing. Try to keep it clean by wrapping all your "constants" in a single global object. The major concern with globals is that you're tied to a single instance of whatever state your globals store, which may or may not be a problem in your case.

You could create a namespace, this way variables would be like global, but you wouldn't have to worry too much for clashes and that kind of stuff. Facebook does that on some of it's APIs.
Just to be safe, here's an example safe namespace implementation:
if(!window.MY_NAMESPACE){
MY_NAMESPACE = {
a_variable : "some value",
a_function: function(params){
return a_variable;
},
};
}
That way you get something like global stuff, without clashing with other variables in the document (or duplicates of your script)

I think it is perfectly OK to use global state for the purposes you mentioned. Just make sure they are written to only once, i.e. not changed during execution. So try to give them names that you won't accidentally overwrite them afterwards (which is always a danger in Javascript - forgeting var and your variable becomes global, i.e. attached to the window object) and preferably put them all into the same structure, to further minimize the danger of name collisions (less names, less collisions).
Also keep in mind, that the variables are not really 'global'; if the user keeps logged in but opens a new window to your site, the 'global' variables are gone. In this case you have to ensure, that there won't be an inconsistency, i.e. the server assumes that given a user is logged in, the variables are set.

Related

Global Variables in Laravel for Views, Controllers, Models etc

I know this question has been asked before, but I am struggling to find an answer that fits my needs, or is for the most up to date version of Laravel.
Basically, I have a load of variables that will be created using data from the Route and the database. For example, I need to use the Route to set a variable called "current_page" which extracts details from the "pages" table using the unique url column. ($current_page = Page::where('url', <url-taken-from-route>)->first();)
$current_page will need to contain several relationships. There are also other global variables such as $current_site (this is a kind of multi-site environment with one home page and nested microsites) etc.
I feel the configuration files are not the right place to create these variables as a) the value of the variables can be nested and complicated and b) they are not constants but data retrieved from a database.
View Composers obviously only work with views, and a Helper class just feels too generic considering we are dealing with pages, sites, and possibly other global variables.
I gather global variables are frowned upon, but these truly are global. The values will always be the same (albeit dynamic) on every occasion, and will be required by most views and controllers.
I have also thought about putting methods in my already existing Page and Site controllers so I can call Page::current(), but am not sure putting static methods in a mostly non-static controller is the right thing to do. Also, this would make a database call every time I called Page::current() rather than having the current page stored in memory somewhere.
For now, I have created a BaseController which all other controllers extend from. I have put these variables in the constructor and manually passed them to the view in each method. (I know that is messy and doesn't work for models).
So what is the best solution here? Where to declare a global variable that can be used anywhere, but doesn't feel hacky?
Thanks

Alternatives to global variables

I have a program that will grab several global settings from an API when first logged in. These values are then used extensively throughout the program. Currently I am storing them in global variables, but it does not seem very OOP.
What are the alternatives to global variables for storing extensively used settings? Use constants? Class variables? Where would I initialize the values through the API call, since this would only need to happen once? I have seen some examples that instantiate a class to get to the variables but that does not make much sense to me.
I would like to set the values on login and after this call the variables everywhere else with a simple expression like Global.myvalue or GLOBAL_MYVALUE
The Singleton Pattern might be handy for this:
https://ruby-doc.org/stdlib-2.1.0/libdoc/singleton/rdoc/Singleton.html
It's hard to give you a concise answer based on the information you provided, but I would avoid using global variables at all costs.
A good starting point would be to think of a class that could be a common ancestor to all the places where you use these variables and store them in that class. If your subclasses inherit from that class, these variables will automatically be available in their context.
Edit: like #seph posted, the singleton pattern seems to be a much better solution though

How to check whether an instance of an ActiveRecord model is up to date?

For testing reasons, I want to check that one of my methods doesn't update a specific entry in my database. Is there a simple way to ask an instance of an ActiveRecord model if its in sync with the database? for instance, if we had a method foobar? that could do this:
old_post = Post.find(1)
updated_post = Post.find(1)
updated_post.update_attributes(name: "this is a new name not like the old name")
old_post.foobar? #should return true, as its attributes are no longer up to date
updated_post.foobar? #should return false, as its attributes match the database directly
So is there a method that acts like foobar, or something like it? Thanks in advance.
I think your problem lies beyond finding a method which tells you wether an attribute has been updated, but in the relationship among the different objects that are instantiated. First it is important to understand, that old_post and updated_post are unrelated ruby objects. They know about how to save their own state to the database, but they do not know about each other.
Therefore your first requirement for foobar? cannot be fulfilled, as old_post will think it is up-to-date as long as no attribute has been updated. In contrast the changed? method will roughly answer in the way you are trying to achieve for updated_post. However it does so because it thinks nothing has happened since it was last saved, this will not be verified against the database upon each call of changed? as this would be wasting a database call in 99.9% of all cases.
This means it is all too easy to generate anomalies between the objects you created as there is no direct connection between the two (except the implicit connection that they once represented the same database row). If you change an attribute in one object (using e.g. title='?' it will change the value of the object and take note of the change in the changed-array. Once you save this object it will save its changed attributes to the database (by creating an individually constructed update-statement).
Another object that is already instantiated (as old_post in your example) will not know about this change and might change other attributes if you are not careful (or even the same ones if they have been changed again). Depending on your database adapter you may try to use the lock! method which will synchronize your object with the database before allowing any modifications. This however will not happen automatically as in most controller methods updates do not conflict nearly often enough to merit the synchronization as it will be idempotent in most cases.
This does not go without saying that rails can not save you from thinking about your transaction semantics if you want to guarantee specific ACID semantics for your controller methods.

How do I create and test environment-specific code?

I have a web app that hopes to track/write bills from different state legislatures. The problem I found, though, is that many states have different rules regarding bill schema, rules for progression (i.e. some states allow you to reconsider a failed bill while others do not), et cetera.
How I'm handling it right now in my models is to create a Bill class and then conditionally reopen the class and add additional fields and validations to the class, depending on environment variables. The intent is for each state to have its own installation of the app, so I would have one with STATE set to OR and make the app use Oregon bill rules.
This has become a huge problem for me, however. Re-opening the class like this works well enough in production, but it becomes really hard to test because the class needs to be opened up at startup and can't be disabled for testing unless I somehow reload the entire program with a different environment variable. I've searched through Google and StackOverflow, but I haven't gotten any results for best practices of what I'm looking for, either because they don't exist or I don't know the name for it.
Since you are asking about environment variables, why not use environment variables?
ENV can be the way to do this, just add the appropriate state in there.
>> ENV['State_Code'] = 'FL'
=> "FL"
>> ENV['State_Code']
=> "FL"
Change it as you want to test the different rules.
This has the advantage of being able to be set from outside of your application, as ENV is read from your environment, not surprisingly.

Code Igniter App: Is-logged-in function: where to put

I'm building a simple login system for the CI based site and I I'm unsure of where to place my function:
is_logged_in()
// check if session logged in stuff exists
// if not check for cookie and reset from that
// return true or false
To start with I need to call this from some public pages so they they can display 'You're logged in as [blah]. Continue to members area'.
Would it make sense to put this in my login model, call it from my controller(s) and then simply pass the result (logged_in: true/false) to my views?
Mostly.
This might be a Model or it might be a Library issue. The question becomes how you are storing whether they are logged in. Personally, I generally put it in a Library which calls a specific Model, it seems less elegant at first, but realistically, I don't want my Model to know anything about my $_SESSION or my $this->session, one of which would be necessary if I wanted to have a good authentication system.
As to how to communicate with the view, there are a couple of ways:
Have it as a special variable passed to the view:
Bonus: It is the most obvious.
Detriment: You will need to place it into every single call to view. This means either you override your loader or you update all of your controls (might be gross).
Have it defined as a constant:
Bonus:By far the easiest if you have logic in the view.
Detriment:Constants are rarely the way to go, they are hard to debug, and it is not a very CodeIgniter way of doing things.
Have a helper function (literally a "helper" function)
Bonus:Universally accessible value which is relatively easy to debug.
Detriment:Requires a helper to know about a Library and/or Model (this is actually true of the built in form_helper, but it still opens up a proverbial can of worms) and it will probably be a one-function helper file.
Conditionally include a view from the controller
Bonus:It removes all logic from your view.
Detriment:You still need to make your controllers aware of the logic.
Personally, I am most likely to use #'s 3 & 4, but each has its advantages.

Resources