Anngularjs reusing html page for multiple results - angularjs

I'm creating a test app in angular that takes a date input, and displays weather information from an API request for today and tomorrow.
I've used the a dayTemperatures.html using ng-include to show the results for today, but want to reuse dayTemperatures.html to show the weather information for tomorrow on the same page.
I think using ng-include makes it harder. The Brute force want I think think of is to create another view with similar variable names, but that is probably defeating the purpose. Any ideas on how this works?
Html:
ng-include="'Angular/weatherInfo.html'"
js:
var onWeatherComplete = function (data)
{
$scope.dailyWeatherDetails = data;
}
Please guide me the correct way to achieve my objective.

Related

Passing value from service into directive

Trying to figure out how to pass a value in service from one direction to another? I'm building a small search app using Elasticsearch and AngularJS. It has 2 pages, home and results. On home, only functionality is autocomplete (using AngularJS UI Bootstrap Typeahead), on results page, display results and search box. I'm trying to use a custom directive to do this.
I basically have everything working EXCEPT, that when on the homepage, pressing the search button just goes to the results page, no search processing is done. AND everything works on the results page, autocomplete and search functions...
I recently put the ng-model(searchTerms) into its own service, but I DI that service into both my controllers. The only thing I can think of is that somehow my ng-model ISN'T getting passed to the directive? I'm stumped... still learning AngularJS directives.
Basically all the service does for searchTerms is
this.searchTerms = null;
Any ideas?
UPDATE I'm on v1.47 and using ngRoute for now.
UPDATE 2 I have 2 way data binding working now. So when a query is submitted on the home page, the searchTerms variable now displays on the results page. However, there is still no results being displayed and no processing being performed. So just 2 way data binding is working.
UPDATE 3
'use strict';
angular.module('searchengine.query-service', [])
.service('queryService', function() {
var searchTerms;
this.searchTerms = null;
});
You can consider these 2 pages 'components', in the more update to date Angular jargon, and you want to navigate between them, passing your search term as a variable.
In your search page, you will need some code along the lines of
$router.navigate(['ResultsPage', {searchTerm: yourSearchTermGoesHere}]);
When the results component activates, it should check for the existence of a search term and perform whatever search processing is done when the search term subsequently changes.
Router docs - https://docs.angularjs.org/guide/component-router. Have a look specifically at the 'Extra Parameters' and 'Lifecycle hooks' section

AngularJS register controller once

That's what I'm doing. There is application with pages and different controls that may be put on pages by site admin/editor. All pages share one ng-app defined on master page. All controls are supplied with .js files with angular controllers. Let's suppose that I have an image gallery block:
<div ng-controller='imageGalleryCtrl'>
do something amazing here
</div>
<script src='imageGallery.js'></script>
Inside script there is a simple controller registration like:
angular.module('myApp').controller('imageGalleryCtrl', ... );
So. If I have 10 image galleries, I'll execute controller registration 10 times. It looks like this will work, but hell - I don't want it to be so =)
For now I just have all controls' scripts registration on a master page, but I don't like it as well, because if there is no image gallery on a page, I don't want it's script be downloaded during page load.
The question is - is there any proper way to understand if controller have been registered in a module already and thus prevent it from re-registering?
---------------
Well, though I've found no perfect solution, I must admit that the whole idea isn't very good and I won't think about it before my site will grow too big to assemble whole angular app on master page.
You should declare your controller but once. Instead of having one controller per gallery, have your single controller handle all image galleries. The controller should make a request to the REST backend to fetch the images of the desired gallery.
I see that instead of ng-view, you're using the ng-controller directive, indicating that probably you're not using Angular's routing. Try switching to using routes.
Have a look at Angular.js routing tutorial. It shows you how to use the ngRoute module. Then, in the next chapter, the use of $routeParams is described. Via the $routeParams service, you can easily say which gallery should be displayed by providing its ID in the URL; only one controller will be necessary for all your galleries.
If you really must check whether a given controller has been declared, you can iterate through the already declared controllers (and services... and pretty much everything else) by checking the array angular.module("myApp")._invokeQueue. The code would probably look something like this (not tested!):
var isRegistered = function(controllerName)
{
var i, j, queue = angular.module("myApp")._invokeQueue;
for (i = 0, j = queue.length; i < j; ++i) {
if (
queue[i][0] === "$controllerProvider"
&& queue[i][1] === "register"
&& queue[i][2][0] === controllerName
) {
return true;
}
}
return false;
};
Bear in mind however that while this may (or may not) work, it's far from being the correct thing to do. It's touching Angular's internal data that's not meant to be used in your code.

How do I get /mylink#sectionid to work in angularjs?

If I wasn't using angular, then the route mylink would be loaded, then the browser would scroll down to the sectionid section.
In Angular it doesn't scroll. I read some completely crazy whacky solutions involving injecting multiple modules and having crazy unique URLs. I refuse to do things like this.
I want my href values to remain standard. Is there any way in Angular to do this?
Keep in mind, if "mylink" was already loaded, then the links work fine, but if I'm on a different page, say "home", then I navigate to mylink#sectionid, then the scrolling won't occur.
(I mean... if Angular can't do this, I would consider that a bug. It'd be absurd to not support a regularly used syntax since the 90s that is still used today)
EDIT: I think the issue may be the amount of AJAX on this website.
It is certainly possible, you will need to inject in $anchorScroll into your controller
The example from the angular site:
function ScrollCtrl($scope, $location, $anchorScroll) {
$scope.gotoBottom = function (){
// set the location.hash to the id of
// the element you wish to scroll to.
$location.hash('bottom');
// call $anchorScroll()
$anchorScroll();
};
}
From anther route you could handle this via parameter being passed into the route and scroll upon initialization based upon the route param.
I'm not a big fan of my solution, but I listen to onRouteChange, then inject anchorScroll and simply call anchorScroll after a 1000 ms timeout and because the hash is already set nothing more needs to be done. [giving time for all angular stuff to work its self out (the site I'm working on has entirely too much AJAX, but I don't have control of the data yet, so there is nothing I can do about that)]
Anywho, manually initiating anchor scroll works. If anyone knows a better way to do this, that'd be swell.

Do we need multiple controllers to implement routes in angularjs?

There is chance that I might not be able to explain my problem properly. Let me try.
I am developing a single page application using angular. This app basically displays the episodes of an online novel series. There is a navigation bar, which has query menus (Like, latest episode, episode of a particular date, episodes with a particular tag, etc). For each of these queries, i want a separate url.
/latest - should display the latest episode
/tag/:tagname - should return all episodes with that tag.
For all these queries, the resultant view is the same (list of episodes). So I will be using the same partial for all routes.
My question is, Should I actually create a new controller for each query? like, LatestEpisodeController, TagController?
Is there anyway I can use the url to determine what the user wants and run that query from within the same controller?
Ofcourse you can use same controller in routing definition, the question is what is the purpose of that? It will be worse to debug it later, if you have a shared functionality it's better to turn it into a factory or service and then use in controllers.
But the answer is YES, you can use same controllers and implement different behaviour basing on i.e. $location.path()
yes you can use single controller for multiple routing..
you can create different functions in controller and in each function do the according job.
In my case I have created different html page for different url and registered same controller for the html pages and in the html page I have called controller method using ng-init in div portion.
You can use same controller and same views as you wish...
$location can help you to get current path or full url if you want and you can call your service depends on your path...
here I write a little example for you to get the idea
PLUNKER

AngularJS calls $http constantly

Im very new to AngularJS (4 hours new) and I'm trying to get an http call working, however what it seems like its happening is Angular keeps calling the http get request over and over again. I'm sure this is because my approach is wrong. This is what I'm trying to do.
snippet of my controller file The webservice works fine. I am running this in a node.js app
function peopleController($scope,$http){
$scope.getPeople = function(){
$scope.revar = {};
$http.get('/location/-79.18925/43.77596').
success(function(data){
console.log(data);
$scope.revar = data;
});
}
}
My list.html file
<div ng-controller="busController">
<div class="blueitem">{{getPeople()}}</div>
</div>
I know I will not see the results since im not returing anything in my getPeople Method but I wanted to see the log output of the result which I did see in chrome, but a million times and counting since angular keeps calling that url method over and over again. Instead it keeps hitting.
How do I get angular to return the response just once?
The problem you are experiencing is linked to the way AngularJS works and - to be more precise - how it decides that a template needs refreshing. Basically AngularJS will refresh a template based on a dirty-checking of a model. Don't want to go into too much details here as there is an excellent post explaining it (How does data binding work in AngularJS?) but in short it will keep changing for model changes till it stabilizes (no more changes in the model can be observed). In your case the model never stabilizes since you are getting new objects with each call to the getPeople() method.
The proper way of approaching this would be (on of the possible solutions):
function peopleController($scope,$http){
$http.get('/location/-79.18925/43.77596').
success(function(data){
$scope.people = data;
});
}
and then, in your template:
<div ng-controller="busController">
<div class="blueitem">{{people}}</div>
</div>
The mentioned template will get automatically refreshed upon data arrival.
Once again, this is just one possible solution so I would suggest following AngularJS tutorial to get better feeling of what is possible: http://docs.angularjs.org/tutorial/
Couple of things. Welcome to angularjs, its a great framework. You probably shouldn't be calling getPeople from the webpage. Instead,
function peopleController($scope,$http){
var getPeople = function(){
$scope.revar = {};
$http.get('/location/-79.18925/43.77596').
success(function(data){
console.log(data);
$scope.revar = data;
});
}
getPeople();
}
and then in html
<div ng-controller="busController">
<div class="blueitem">{{revar|json}}</div>
</div>
Also, I would recommend you looking into the ngResource, especially if you are doing CRUD type applications.
Hope this helps
--dan

Resources