In my AngularJS app, I need to retrieve multiple collections of static data from remote REST endpoints. Those data collections will be used throughout the entire application life cycle as static lookup lists. I would like for all those lists to be populated upon the initial application startup, and to be retained and made available to multiple controllers. I would prefer not to load any additional data dynamically, as one of the assumptions for this particular app, is that, once loaded, any further network connections may not be available for a while.
It is OK to take an initial hit, as the users will be preoccupied by reading a static content of the first page anyway.
I was thinking of making this mass loading a part of the initial application run block, and stick all this static data into various collections attached to the $rootScope (which would make that available everywhere else)
What is the best way to handle this requirement?
Interestingly enough, I just wrote a blog post about extending the script directive to handle this very scenario.
The concept is simple. You embed JSON data in your page when it loads from the server like so:
<script type="text/context-info">
{
"name":"foo-view",
"id":34,
"tags":[
"angular",
"javascript",
"directives"
]
}
</script>
Then you extend the script directive so it parses the data out for you and makes it available to other parts of your application via a service.
if(attr.type === 'text/context-info'){
var contextInfo = JSON.parse(element[0].text);
//Custom service that can be injected into
// the decorator
contextInfoService.addContextInfo(contextInfo);
}
You can see a live demo of it here: http://embed.plnkr.co/mSFgaO/preview
The way I approach this is to use a service (or a collection of services I nest), and set caching to true in the $http get functions. This way the service can be passed into any controller you desire, having cached results available to you without the need for additional http requests.
I can try to put this into an example if this is unclear to you, let me know.
edit: you can either wait for the first call to this service to do this caching, or do this on app load, either way is possible.
Related
I wonder what is the best practice for storing lists from different API's and display them without the need to make redundant API requests.
Suppose user logged in - i want to store all the pages static lists for dropdown menus in a way that they will be available to all the controllers - by doing the API requests once.
The options that i came across are the following:
creating a factory and store the data in $rootScope.
Use sessionStorage.
What is the best way?
Consider storing data in rootscope a very bad practice.
I'd suggest using this package
https://github.com/jmdobry/angular-cache
You have nicely explained inside documentation why would you use this package instead of angulars built in $cacheFactory service.
In my Angular SPA, there's some data loaded from the backend that is used throughout the application. This data doesn't change while the app is in use, so to keep things slick for the users I'd like to only load this data once. I can see two possible solutions here:
Load the data when the app is first initialised and attaching it to $rootScope using angular.module.run()
or
The first controller to need the data loads it, and then puts it... somewhere... where everything else can get to it.
Which approach is the "most Angular" way to do this, and how would I start to implement it? Most of the questions on SO seem to be about loading data with the controller rather than when the app itself starts. I'm using 1.4.7 with UI Router if that makes a difference.
You could implement a service which has been sugested by others and ALSO make the service load the data in a lazy way. (Lazy loading pattern described here: https://en.wikipedia.org/wiki/Lazy_loading)
I am working on a single page app using AngularJs Framework.
The website is kind of social networking and thus consists of various kinds of data to be fetched from server.
Will it be good to be RESTful and make each entity a 'resource' or implement other way to get 'aggregated JSON' response, since RESTful results in too many calls ?
If non-RESTful approach is used, ( say by using $http service ), then how can I still maintain the modular architecture of app.
Consider example for clarification:
let the server return:
{
user: {
name: ....
....,
projects: [{
....
....
}],
...
}
}
How can I create modules such as User and Projects, each with its own functions and logically separate and independent.
Its almost similar to making single $http request and distributing response to many services.
Any help is appreciated.
Disclaimer - I am by no means a REST expert or purist
This is a very good question and something I struggled with as well. I just couldn't justify having X number of REST calls to display a single form/page, where X could sometimes be fairly large. The solution I ended up with which seems to work reasonably well in my case was a hybrid approach. I use aggregates (View Models) to render the forms/pages, these View Models I get from the server with a single API call. For create/update/delete operations I extract the actual resource from the View Model on the client and post that using a more RESTful approach.
This gives me best of both worlds, low number of API calls to display page, RESTful approach on post which reduces network overhead.
In addition to the above I use an approach I saw on breeze.js documentation which seems to work really great as well, on application startup I load all commonly used static lookup data (typically data used for dropdowns/select lists) in a single LookupsAggregate and cache that on the clients. This model is then available from the start and no need to refetch them everytime you need to display a dropdown/select lists.
I would like to know what is the proper way to get data from backend when I want to use angularJs (or similar) in my web app?
The only way I see is to render html (static html with js scripts - e.g. angularjs) with no data from backend and then download data via ajax requests from my backend API. But I think this solution is not good because of many HTTP requests:
For example I have blog website, I want to show a post, comments, and the related posts on the sidebar. So probably I need to make at least 3 HTTP requests to get the data unless I will prepare API to get all I need in one request.
I can also imagine websites that could have much more HTTP requests. Is it a proper way to do this? Doesn't it overload a server? Or my way of thinking is so wrong?
It is either websockets or HTTP requests. Preparing API to get all in one request is one option. Another two options are XMLHttpRequest/iframe streaming which is a method of a technique known as Comet.
I would go with websockets since it is supposed to solve the problem that was previously solved with weird applications like iframe streaming. There are libraries that properly handles fallbacks if the browser does not support websockets:
web-socket-js ( this needs a websocket server )
Socket.IO ( this has a node.js module and also implements a kind of unnecessary protocol on top of websocket protocol )
If you choose the old methods there will be many problems waiting for you on the road like XmlHttpRequest.responseText while loading (readyState==3) in Chrome
I think you have to distinguish two cases:
You render the page for the first time.
You update parts of your page when something changes
Of course in the second case it makes sense to fetch only parts of the page via individual HTTP requests. However, in the first case you can simply serialize your complete model as one JSON object and embed it in the page like this:
<script type="text/javascript">
var myCompleteModel = { /* Here goes your model */ };
<script>
The controllers of the components on your page can then access this global variable to extract the parts being relevant for them. You can also wrap access to the initial model in a service to avoid accessing a global variable in all your controllers.
I am working on a small piece of an angular project and need to define some constants that are derived from values in a database. I have a REST endpoint that delivers the data I need, but I can't figure out how to load the values before the app gets automatically bootstrapped.
I cannot modify the application to a manual-bootstrapping process. Typically a resolve would be used upon navigation, but I have other components (like modals) that use the constants that aren't necessarily part of any route.
What would be ideal would be some sort of "resolve", but at the application layer. I do have the ability to load npm and bower packages, but anything that changes to a 'manual' bootstrapping method isn't allowed.
In that case I can recommend you to use a $rootScope. I don't understand very well your needs, but everything that is stored in $rootScope will be available in all views. Just fill it with your REST service inside the first or main view of your app. Although, it is important to understand that if you refresh you page, the $rootScope will be as well refreshed, this is, all of your REST calls will be launched again. (Navigating inside angular views is NOT refreshing the page unless you ask for it using window.reload() or similar; it is just the same page with a new controller)
To avoid this last behavior (page refresh) you could also use local Storage, which is basically a small amount of memory inside your browser where you can save any data that you want to keep regardless of your page refreshes. I used in one of my projects this library: https://github.com/grevory/angular-local-storage
It was useful for saving permanent stuff until user logs out.
Hope it helps! And sorry if I am answering something not useful for you
Cheers
It seems that the only way to effectively load some values from a service prior to the app starting is to make the service-call to and then manually bootstrap the app. The idea of an app-wide "resolve" doesn't seem to exist.