Problem Statement
I'm working on building out a single-page Django web app and am trying to implement the following functionality:
- All viewers of the page are associated with a state. There are buttons on the page which enable viewers to change their state.
- The application stores a list of all current viewers of the page, and their associated states. Whenever a user changes their state, this stored list of viewers updates with this new information.
- The application should display how many people are online (viewing the page) at a given time.
Blockers
I'm unsure of how to collect a list of all current viewers of a page in Django, nor how to collect how many users are currently viewing the page.
Ideally, my application would not require a login to use: therefore, I'd rather either associate viewer state with a user object that doesn't require sign-in, or not associate viewer state with a user object (I'm still new to user objects though, so forgive me if this point doesn't make complete sense).
What I'm Looking For
A discussion of higher-level strategies which I can use to implement this functionality, or other places to look to gain insight in tackling my problem. I'm pretty new to Django, so I'd appreciate it if answers also direct me to locations in my Django project which are of relevance (e.g. "Consider doing X in views.py, then..."). Alternatively, if there are GitHub projects you know of with similar functionality, if you could direct me to them to investigate further, that would also be appreciated.
I'd be happy to offer further clarification as required. Thanks in advance!
Is there a way to distinguish access through external link (e.g. from history, or from other site) or access by link from other page of the same app in beforeModel handler?
Here is my case:
If user accesses my app by direct link and requests route requiring authenticated user, I make a transition to index route and show popup with an authorization form.
If user is already on my site and trying to access the requested route requiring authenticated user, I abort transition and show the popup on a previous page.
I have no separate page for authentication.
My current work around is to check some strange private property called sequence of transition object which has been passed to beforeModel handler, if transition.sequence === 0, then user came from "outside", otherwise user follow by link "inside" my app.
I think this is a bad way to achieve the goal, core developers can remove sequence property any time.
So, is there any clean way to distinguish whether current route was requested from "outside" or "inside" of my app?
I'll appreciate any help, thanks!
P.S. EmberJS v1.10.0
P.S.S. Sorry for my English
If you want to avoid using an internal call you could keep track of the history in the application route something like this Implementing a "conditional" back button in ember.js
But in your router would probably be better since controllers are going away soonish.
You could probably use http://emberjs.com/api/classes/Ember.Route.html#event_didTransition
UPDATE after chatting
Logic for counting, aborting, etc transitions can be done in the willTransition action in application route http://emberjs.com/guides/routing/preventing-and-retrying-transitions/
I configured my Ember App to run with the localstorage_adapter.
I am new to Ember and probably, I don't grasp all its details yet. Still, from what I understand, when you refresh the browser the ember store data should not be lost. Obviously the localstorage is not affected by a browser refresh.
This is what happens:
1. after login, I fetch the data from the server and store it using store.push() or store.pushMany()
2. play around with the application
3. at some point hit a browser refresh (or on my Android phone when I hit the home button, the browser get's closed and when I open it again from the running applications window, it opens and does a refresh by default)
4. the page which I was on gets messed up
For example, I'm on page where I display the user name, a question and a list of possible answers. Please note that there are 20+ questions in store. I know this by using Ember Inspector. I hit refresh, now the store has 1 user entity (the logged user) which is fine, 1 question only (not good at all), the one which was displayed on the page, and the answers store is empty. All other entities (which have nothing to do with this page) are gone too! So what I can see on my web page is the user name and the question's text, no answers, no way to move forward.
Is this supposed to happen? The "in memory" store gets cleared and not repopulated from localstorage?
thanks!
Is this supposed to happen? The "in memory" store gets cleared and not repopulated from localstorage?
Yes, it is supposed to happen. To understand why, first remember that the localStorage in your browser is seen as a server. To Ember-Data, there's absolutely no difference between your localStorage and a Rails server with a REST API. Ember-Data treats them both as asynchronous data stores that it communicates with through an adapter. The LocalStorageAdapter is no different.
What does this mean? It means that your store only gets populated with records that you specifically request. Just as Ember-Data doesn't try to get all of the records from a Rails server at startup, it doesn't try to get all of the records from your localStorage at startup. This is by design. Ember-Data doesn't play favorites; it treats all adapters equally.
In order to repopulate your store with entries from the localStorage, use the store's find() method like you would in any other situation. The calls with be quick, although still asynchronous.
Also, as Beerlington mentioned, you must save your data explicitly if you want it to go into the localStorage. The store won't place it there automatically.
Intro
I am working on an e-commerce website. And we want to add a feature where a user can refer others via a custom link e.g.:
http://example.com/a1t2312 or http://example.com/?ref=a1t2312 (a1t231 being the referral code).
A user following such a link, will navigate a few pages on the site. And if he reached the 'buy' page and purchases something - the original referrer will get a discount.
The question is:
What is the best method to track the referral code? Put it in the user's cookies? Stick it somehow into the session? Other method?
I would definitely use cookies, as it is the easiest (but not foolproof, though). Sessions are by site, so that won't work, unless the receiving site has some code to handle the user.
All methods mentioned by you are OK. If I were you I would consider using sessions because it is more natural to me.
disclaimer: session has some limitations when you want to build application ready for heavy-load. For complicated demployment scenarios avoiding sessions might be a good choice.
You're building a web application. You need to store the state for a shopping cart like object during a user's session.
Some notes:
This is not exactly a shopping cart, but more like an itinerary that the user is building... but we'll use the word cart for now b/c ppl relate to it.
You do not care about "abandoned" carts
Once a cart is completed we will persist it to some server-side data store for later retrieval.
Where do you store that stateful object? And how?
server (session, db, etc?)
client (cookie key-vals, cookie JSON object, hidden form-field, etc?)
other...
Update: It was suggested that I list the platform we're targeting - tho I'm not sure its totally necessary... but lets say the front-end is built w/ASP.NET MVC.
It's been my experience with the Commerce Starter Kit and MVC Storefront (and other sites I've built) that no matter what you think now, information about user interactions with your "products" is paramount to the business guys. There's so many metrics to capture - it's nuts.
I'll save you all the stuff I've been through - what's by far been the most successful for me is just creating an Order object with "NotCheckedOut" status and then adding items to it and the user adds items. This lets users have more than one cart and allows you to mine the tar out of the Orders table. It also is quite easy to transact the order - just change the status.
Persisting "as they go" also allows the user to come back and finish the cart off if they can't, for some reason. Forgiveness is massive with eCommerce.
Cookies suck, session sucks, Profile is attached to the notion of a user and it hits the DB so you might as well use the DB.
You might think you don't want to do this - but you need to trust me and know that you WILL indeed need to feed the stats wonks some data later. I promise you.
I have considered what you are suggesting but have not had a client project yet to try it. The closest actually is a shopping list that you can find here...
http://www.scottcommonsense.com/toolbox.aspx
Click on Grocery Checklist to open the window. It does use ASPX, but only to manage the JS references placed on the page. The rest is done via AJAX using web services.
Previously I built an ASP.NET 2.0 site for a commerce site which used anon/auth cookies automatically. Each provides you with a GUID value which you can use to identify a user which is then associated with data in your database. I wanted the auth cookies so a user could move to different computers; work, home, etc. I avoided using the Profile fields to hold onto a complex ShoppingBasket object which was popular during the time in all the ASP.NET 2.0 books. I did not want to deal with "magic" serialization issues as the data structure changed over time. I prefer to manage db schema changes with update/alter scripts synced with software changes.
With the anon/auth cookies identifying the user on the client you can use the ASP.NET AJAX client-side to call the authentication web services using the JS proxies that are provided for you as a part of ASP.NET. You need to implement the Membership API to at least authenticate the user. The rest of the provider implementation can throw a NotImplementedException safely. You can then use your own custom ASMX web services via AJAX (see ScriptReference attribute) and update the pages with server-side data. You can completely do away with ASPX pages and just use static HTML/CSS/JS if you like.
The one big caveat is memory leaks in JS. Staying on the same page a long time increases your potential issue with memory leaks. It is a risk you can minimize by testing for long sessions and using tools like Firebug and others to look for memory leaks. Use the JS Lint tool as well as it will help identify major problems as you go.
I'd be inclined to store it as a session object. This is because you're not concerned with abandoned carts, and can therefore remove the overhead of storing it in the database as it's not necessary (not to mention that you'd also need some kind of cleanup routine to remove abandoned carts from the database).
However, if you'd like users to be able to persist their carts, then the database option is better. This way, a user who is logged in will have their cart saved across sessions (so when they come back to the site and login, their cart will be restored).
You could also use a combination of the two. Users who come to the site use the session-based cart by default. When they log in, all items are moved from the session-based cart to a database-based cart, and any subsequent cart activity is applied directly to the database.
In the DB tied to whatever you're using for sessions (db/memcache sessions, signed cookies) or to an authenticated user.
Store it in the database.
Do you envision folks needing to be able to start on one machine (e.g. their work PC) but continue/finsih from a different machine (e.g. home PC)? If so, the answer is obvious.
If you don't care about abandoned carts and have things in place for someone messing with the data on the client side... I think a cookie would be good -- especially if it's just a cookie of JSON data.
I'd use an (encrypted) cookie on the client which holds the ID of the users basket. Unless it's a really busy site then abandoned baskets won't fill up the database by too much, and you can run a regular admin task to clear the abandoned orders down if you care that much. Also doing it this way the user will keep their order if they close their browser and go away, a basket in the session would be cleared at this point..
Finally this means that you don't have to worry about writing code to deal with de/serialising the data from a client-side cookie, while later worrying about actually putting that data into the database when it gets converted into an order (too many points of failure for my liking)..
Without knowing the platform I can't give a direct answer. However, since you don't care about abandoned carts, then I would differ from my colleagues here and suggest storing it on the client. Why store it in the database if you don't care if it's abandoned?
Then again, it does depend on the size of the object you're storing -- cookies have their limits after all.
Edit: Ahh, asp.net MVC? Why not use the profile system? You can enable an anonymous profile if you don't want to bother making them log in
I'd say store the state somewhere on the server and correlate it to the user's session. While a cookie could ostensibly be an equal place to store things, if you consider security and data size, keeping as much data on the server as possible becomes a good thing.
For example, in a public terminal setting, would it be OK for someone to look at the contents of the cookie and see the list? If so, cookie's fine; if not, you'll just want an ID that links the user to the data. Doing that would also allow you to ensure the user is authenticated to the site in order to get to that data rather than storing everything on the machine - they'd need some form of credentials as well as the session identifier.
From a size perspective, sure, you're not going to be too concerned about a 4K cookie or something for a browser/broadband user, but if one of your targets is to allow a mobile phone or BlackBerry (not on 3G) to connect and have a snappy experience (and not get billed for the data), minimizing the amount of data getting passed to the client will be key.
The server storage also gives you some flexibility mentioned in some of the other answers - the user can save their cart on one machine and resume working with it on another; you can tie the cart to some form of credentials (rather than a transient session) and persist the cart long after the user has cleared their cookies; you get a little more in the way of fault tolerance - if the user's browser crashes, the site still has the data safe and sound.
If fault tolerance is important, you'll need some sort of persistent store like a database. If not, in application memory is probably fine, but you'll lose data if the app restarts. If you're in a farm environment, the store has to be centrally accessible, so you're again looking at a database.
Whether you choose to key by transient session or by credentials is going to depend on whether the users can save their data and come back later to get it. Transient session will eventually get cleaned up as "abandoned," and maybe that's OK. Tying to a user profile will let the user keep their data and explicitly abandon it. Either way, I'd make use of some sort of backing store like a database for fault tolerance and central accessibility. (Or maybe I'm overengineering the solution?)
If you care about supporting users without Javascript enabled, then the server side sessions will let you use URL rewriting.
If a relatively short time-out (around 2 hours, depending on your server config) is OK for the cart, then I'd say the server-side session. It's faster and more efficient than accessing the DB.
If you need a longer persistence (say some users like to leave and come back the next day), then store it in a cookie that is tamper-evident (use encryption or hashes).