We can assume that: we have a SPA application consist of a profile page and a followerList page. The state tree is as shown in the following:
{
profile: { name: xx, sex: xx },
followerList: []
}
We can open a follower list page from a profile page A, and then open a profile page B from the follower list page. In my application, page A and page B share the same reducer profile.
Here is the problem: when page B rendered, the profile in state tree has been changed by B's info; when it returns back to page A, it is supposed to keep A's info, but it has also been rendered by B's info.
So far I've got two solutions:
Using a profileList to keep all profile pages have been opened. It means that I have to keep a list for every page which can be opened recursively. Caching profile data is really a good method, which is also very helpful to cut the request. But it means that I have to make the state tree more complex, and inject more concept (e.g. reselect). As I'm building the architecture of our app, increasing the complexity is not friendly to other developer.
Re-rendering the profile page when the page is returned. I don't think it's an elegant way.
How can I solve this problem?
Related
We are trying to test a page which at one point redirects the execution to another page for login credentials. After this we need to go back to initial page and continue from where it stopped before redirection.
How can I achieve this?
I tried with roles but this wouldn't keep the data on the initial page and instead reloads the page which then is empty. Also with roles you always go back to same page.
Any suggestions?
Using the roles mechanism is the only built-in way to save and restore cookies/storages. Each role has its role constructor with the initialization function. Cookies and storages are saved only after a role is initialized. It means that you can try to use a role for the first part of your test and save the page state:
const role1 = Role(basePage, {
// do smth
});
const role2 = Role(loginPage, {
// login
});
test('test', async t => {
await t.useRole(role1); // state is saved
await t.useRole(role2); //
await t.useRole(role1); // state is restored
})
If this approach does not meet your needs, you can try writing some custom logic to save/restore the state. Please follow this link https://github.com/DevExpress/testcafe/issues/2142 to see an example of a custom solution of how to save/restore localStorage via CustomFunctions.
There may be some design considerations worth making in the app itself, perhaps some usage of local or session storage is in order. Testing aside, wouldn't the user also experience this disappearing data if they manually reloaded, for whatever reason?
In my experience with TestCafe, there were instances where I had to do more in each test than I cared to, to workaround similar issues, including times I couldn't use roles and simply cooked up my own reusable login function that I called here and there.
That seems to be one of the limitations with TestCafe in conjunction with testing such functionality (the SPA paradigm, which perhaps this is). It's going to reload pages, but if I remember correctly there was a discussion about it in their issue tracker, so it may be worth browsing there as well if you haven't already.
I have a Layout page which sets up the list of Projects in the application using Telerik's ComboBox as shown. The combobox allows user to select a project he/she wants to work on.
Once a selection is made, I want all subsequent actions in the application should correspond to the selected Project. I can preserve the Project information in a Session but then if user chooses to open this in a new tab and in 2nd tab users switches to a different Project and comes back to the first tab and refreshes the page then the session information (Project) would have changed which will create issues in my application.
So, what is the best way for me to persist Project information of the Layout.cshtml controls so that I can use it in my application such that every page that is rendered uses the currently/correctly selected values.
Tempdata / QueryStrings came to my mind but i don't know whether they will be reasonable solution to my problem. If yes, then how should I use them generically (specially querystrings) without complicating my solution?
localStroage and sessionStorage also seems like relevant solutions but then how do I use them in scenario where user opens a new tab from existing page? How will the Project # will persist on the newly opened page/window/tab?
something like this is achievable, if you make sure the url changes when a selection is made.
So let's say you select project C-1379 in your dropdown box, at that point your url could become http://localhost:58692/pid=C-1379.
from now onwards, your page can load the desired data, retrieving its required information from the query string. Do not use session or localstorage or anything like that as it won't work.
This way, you can still load your list of projects in your layout page, and you can select one based on the query string value and then load some default values via api calls to the back end.
If all your work from now on is done based on api calls, for example, you have some properties that you change and then you issue a POST to update said details then this is very easily done as well.
telerik controls usually have some events associated with them. the one you are using should have an onChange or something like that. This where where you would update the query string with the value of the project selected and then you can proceed to do what you need
I can preserve the Project information in a Session but then if user
chooses to open this in a new tab and in 2nd tab users switches to a
different Project and comes back to the first tab and refreshes the
page then the session information (Project) would have changed which
will create issues in my application.
I would have thought this is the desired behavior... take stackoverflow.com as an example, if I change my username in one browser-tab, I would expect my username to be updated in other browser-tabs as well... and that's what happens if I refresh my other tab.
There is no built in solution for maintaining user info in different browser tabs separately... the only way to achieve this, is by sending project name back and forth in the URL... but then you would loose this info if user changes the URL... In my opinion, this is an ad hoc solution and does not worth the effort of development, because it's a very uncommon scenario.
Getting to your options:
Storing user info is a very typical use case for session variable.
TempData is stored in Session by default. Though you can write
your own custom TempDataProvider and store it somewhere else (e.g.
database, cookie, etc). See Brok Allen's Cookie TempDataProvider
as an example. One advantage of using Cookie is that you send your
session variable back and forth with the request so you don't need to
worry about Sticky Sessions.
You can of course use a permanent storage, such as DB/Disk.
If the project name is not a sensitive info then I don't see any issue in passing it in Query String.
I have 2 views in my SPA built up using durandal. I have a form (consider basic employee information form) in the first view. Also, I am having a button in the view called "upload" which routes to a different view to upload some documents. Once user finishes uploading, it redirects back to my first view and when it does, the first view reloads (renders) again loosing all my previously entered values. Same is the case when I press browser back button on my second view (the upload page).
Any solution on how I can persist data in this case ?
Thanks.
Posting code would make it a bit easier but I would think you'd need to maybe store what's entered in LocalStorage or something and then retrieve it later?
AmplifyJS can make this easier.
I've gone through the introduction of the new graph options. I'm not a developer, but a marketer and I need to present to my superiors what can be done with the graph.
I don't understand one thing: If I, for example, have a "Cook" button, and the user presses it, Is it possible to have two actions at the same time:
1. publish to user's feed (or ticker)
2. proceed to a page on my website?
Yes, you can have both actions (post to Graph and redirect user to new content) on a single client side click of an HTML element. You do that both clientside or from a server.
Hope you are having a great day.
I have a page where I let users browse related items (photo albums) posted by other users.
I show the album thumbnail, title, author, ratings views and category for each albums.
Now the number of related items can get large say 500 photo albums is related to a album user is viewing. I just show first 20 and drop a link saying 'View All'
Once the user clicks View All I take him to a page where I display 50 items per page.
Option 1: using a repeater\grid control
When user clicks a page I get the right items (using sql) and bind the result to the grid
The page is refreshed and user sees new page. So one big request and user sees all thumbs.
Option 2:
when user clicks the pager I use Ajax to get the thumbnail file name, title, rating, author etc.
Then I build the grid manually and set the src attribute of element using javascript
Then I append the resulting grid to a div. User sees the new grid without page refresh.
My concerns:
I have the thumbnails and all image files in file system (not database)
In second approach javascript will send 50 separate request to web server to get the image files. This will cause a lot of requests on the web server. Large concurrent users will flood the server with image file requests.
What is the best & efficient way to do paging and storing user files?
Is my app going to die by putting the images in file system since the app should handle millions of photos?
If you aren't already using one, a CDN (content delivery network, like Amazon S3 etc) will help (so you can download from multiple places concurrently).
Also, instead of requesting one image, request a page from the server. Let the server decide how many images to return.
You could try some css sprite techniques.
Definetely you shouldn't use Option 1 since it would take a lot of time for the page to load
Aldso the second alternative id not so good either.
You can use your GridView/ListView control but use server side paging to get the data. This way you could load only the information that is needed per page.
You can see how to implement a stored procedure for server side paging here : http://www.sqlteam.com/article/server-side-paging-using-sql-server-2005
Then you can bind the individual page the PageIndexChanging event handler of your Gridview
so only the page that is needed is actually loaded.