Hi guys I've been trying for a while now to sort data braught from openweathermap.org using the api provided by the site and the ng-repeat feature in angularjs. for some reason i can't seem to get it to work... what I'm trying to do is to first display all of the gathered data and then sort it using the input field.
Javascript
var app = angular.module('weatherApp', []);
app.controller('weatherController', function($scope, $http) {
$http.jsonp('http://api.openweathermap.org/data/2.5/weather', { params : {
q : $scope.city,
units : $scope.units,
callback: 'JSON_CALLBACK',
APPID: $scope.id
}}).success(function(data){
$scope.data = data;
});
$scope.units = 'metric';
$scope.id = 'e08f9689f06c1b6eddb44396c749eb54';
$scope.reset = function(){
return $scope.city = "";
};
});
HTML
<div ng-app="weatherApp" ng-controller="weatherController">
<input ng-model="city.name" placeholder="City" />
<button ng-click="reset()">Reset</button>
<ul>
<li ng-repeat=" x in data | filter : city">
{{x.name}}
</li>
</ul>
You could try to set the $scope.id and $scope.units before calling $http.jsonp. Seems to me that the values are used in the parameters before being set. Try changing this to:
var app = angular.module('weatherApp', []);
app.controller('weatherController', function($scope, $http) {
$scope.units = 'metric';
$scope.id = 'e08f9689f06c1b6eddb44396c749eb54';
$http.jsonp('http://api.openweathermap.org/data/2.5/weather', { params : {
q : $scope.city,
units : $scope.units,
callback: 'JSON_CALLBACK',
APPID: $scope.id
}}).success(function(data){
$scope.data = data;
});
$scope.reset = function(){
$scope.city = '';
};
});
Related
So, I was able to select Items of my list, but the aim is to pass the data of the selected list in another /route when I click on it. I would need a bit of help because I don't really know how to proceed please. If you know punker examples do not hesitate to tell me :)
Bellow is my optionSuggestionController
app.controller('optionSuggestionController', ['$scope', '$http', function($scope, $http) {
$http.get('suggestions.json')
.then(function(res){
$scope.suggestions = res.data;
});
$scope.setMaster = function(suggestion) {
$scope.selected = suggestion;
}
$scope.isSelected = function(suggestion) {
return $scope.selected === suggestion;
}
}])
Bellow is my list of data
<ul class="list-holder">
<li ng-repeat="suggestion in suggestions" ng-class="{active : isSelected(suggestion)}">
<a ng-click="setMaster(suggestion)">{{suggestion.fromto}}</a>
</li>
</ul>
Bellow is my suggestions.json
[{ "fromto": "Dublin to London", "img": "http://placekitten.com/100/100" },
{ "fromto": "Dublin to Paris", "img": "http://placekitten.com/100/100" },
{ "fromto": "Dublin to Mexico", "img": "http://placekitten.com/100/100" }]
I think you can use the provider '$rootScope'.
$rootScope.selected = suggestion;
You can access this data in an other controller.
Hope it helps.
I have two suggestions:
You can use the provider '$rootScope'.
$rootScope.selected = suggestion;
Or get param via url by provider '$route'.
var suggestion = $route.current.params.suggestion;
You can use Service or Factory to share your data between controllers, I create a Factory with your codes and call it on a control to use.
app.controller('optionSuggestionController', function ($scope, $filter, $timeout, $timeout, $http, testFactory) {
testFactory.get(function (resp) {
console.log(resp);
$scope.suggestions = resp;
});
});
app.factory('testFactory', function ($http) {
var databaseFactory = {};
databaseFactory.get = function (callback) {
return $http.get('suggestions.json').then(function (response) {
databaseFactory.returnedData = response.data;
callback(databaseFactory.returnedData);
});
}
return databaseFactory;
});
I want to increment the data via Button click or scroll.
I have a function which loads the data after button click loadDataQueryDB(param, param, param). With that, I am passing data to MongoDB query.
Well how can I increment my var limit = 50; + 5; after each button click?
Node.js
router.get('/load', function(req, res) {
var skip = 0;
var limit = 50;
var place_val = req.query.place;
var category_val = req.query.category;
var specCategory_val = req.query.specCategory;
if(category_val, specCategory_val, place_val){
Experiences
.find({category : category_val, city:place_val})
.lean()
.skip(skip)
.limit(limit)
.exec(function(err, docs_accommo) {
res.send(docs_accommo);
console.log("First");
});
}
});
Angular.js
app.controller('loadData', ['$scope', '$http', '$window', '$upload', '$rootScope',
function($scope, $http, $window, $upload, $rootScope) {
$scope.loadDataQueryDB = function(place_value, category_value, specCategory_value){
console.log(place_value);
console.log(category_value);
console.log(specCategory_value);
$scope.datafront = [];
var options = {
place : place_value,
category: category_value,
specCategory : specCategory_value
};
$http.get('/load',
{params: options})
.success(function(data) {
$scope.datafront = data;
});
};
});
HTML
<div ng-click="loadDataQueryDB(place, category, specCategory)">
<div ng-repeat="x in datafront | limitTo:? track by x._id" ng-cloak>
{{x}}
</div>
</div>
<button class="btn btn-default" style="float:right; margin-bottom:20px;"/>
Something like the code below, using services and http promises, the data returned form the server its on promise.data.
app.controller('loadData', ['$scope', '$http', '$window', '$upload', '$rootScope','dataService',
function($scope, $http, $window, $upload, $rootScope, dataService) {
$scope.loadDataQueryDB = function(place_value, category_value, specCategory_value){
console.log(place_value);
console.log(category_value);
console.log(specCategory_value);
$scope.datafront = [];
var params = {
place : place_value,
category: category_value,
specCategory : specCategory_value
skip : $scope.skip,
limit : $scope.limit
}
dataService.getData(params).then(function(promise){
$scope.dataFront = promise.data;
//Increment the limit by ten
$scope.limit =+ 10;
})
};
});
app.module('dataService').factory('dataService',['$http',function ($http) {
var service = {};
factory.getData= function (params) {
var promise = $http({
method: 'GET',
url: '/load',
params: params
});
return promise;
}
return service;
}]);
You should have only the gets that return views on the router and the rest of the get and post calls on a service, at least I develop like that and its more confortable.
I already have seem other topics with this kind of issue, but no one could help me... So here is my issue:
I have a navbar with a button for search, this buttons makes and get request from a webservice and returns a json object which must be apply to fill an table list. The problem is, my button and my table are in separated controllers, and it does work like I expected.
var app = angular.module('clientRest', []).controller('lista', ['$scope', 'loadLista', function($scope, loadLista) {
$scope.contatos = loadLista.getContatos();
}]).controller('pesquisa', ['$scope', '$http', 'loadLista', function($scope, $http, loadLista) {
$scope.listar = function() {
$http.get("http://localhost/wsRest/index.php/contato").success(function(response) {
loadLista.setContatos(response);
});
};
}]).service('loadLista', function() {
var contatos = [];
return {
getContatos: function() {
return contatos;
},
setContatos: function(c) {
contatos = c;
}
};
});
My code...
When I call listar() from pesquisa controller I need to send received data to $scope.contatos from lista controller to make my ng-repeat work, everything with a single click.
How can I do it?
Thanks everyone
Better to use a service to share data between two controllers / modules as this might be the best approach. You can refer the code segment given below to understand the concept.
angular.module('app.A', [])
.service('ServiceA', function() {
this.getValue = function() {
return this.myValue;
};
this.setValue = function(newValue) {
this.myValue = newValue;
}
});
angular.module('app.B', ['app.A'])
.service('ServiceB', function(ServiceA) {
this.getValue = function() {
return ServiceA.getValue();
};
this.setValue = function() {
ServiceA.setValue('New value');
}
});
In order to trigger the data receipt event, you may use
Broadcast / emit messages - with #broadcast / #emit
An angular promise with a call back
Controller initiation function to reload the previously read information from a service
.controller('MyController', function($scope, ServiceA) {
$scope.init = function() {
$scope.myValue = ServiceA.getValue();
};
// Call the function to initialize during Controller instantiation
$scope.init();
});
Use $rootScope.$emit to emit a change event when setting the variable and use $on to get the value in the lista controller. I used customListAr here just to demostrate a button click. Does this help?
var app = angular.module('clientRest', [])
.controller('lista', ['$scope', 'loadLista', '$rootScope',
function($scope, loadLista, $rootScope) {
console.log(loadLista);
$scope.contatos = loadLista.getContatos();
$rootScope.$on('change', function() {
$scope.contatos = loadLista.getContatos();
});
}
])
.controller('pesquisa', ['$scope', '$http', 'loadLista',
function($scope, $http, loadLista) {
$scope.listar = function() {
$http.get("http://localhost/wsRest/index.php/contato").success(function(response) {
loadLista.setContatos(response);
});
};
$scope.customListAr = function() {
loadLista.setContatos(["item 1" , "item 2", "item 3"]);
}
}
])
.service('loadLista', ['$rootScope',
function($rootScope) {
var contatos = [];
return {
getContatos: function() {
return contatos;
},
setContatos: function(c) {
contatos = c;
$rootScope.$emit('change');
}
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="clientRest">
<div ng-controller="lista">
<ul>
<li ng-repeat="a in contatos">{{a}}</li>
</ul>
</div>
<div ng-controller="pesquisa">
<button ng-click="customListAr()">Click Me</button>
</div>
</div>
Your problem is that when you do $scope.contatos = loadLista.getContatos(); you are setting a static value, and angular is unable to effectively create a watcher for that object because your setContatos method is creating a new object each time. To get around this, have the controller's scope hold a reference to the parent object and then it will automatically have a watcher on that object.
var app = angular.module('clientRest', [])
.controller('lista', ['$scope', 'loadLista', function($scope, loadLista) {
$scope.contatos = loadLista.contatos;
}])
.controller('pesquisa', ['$scope', '$http', 'loadLista', function($scope, $http, loadLista) {
$scope.listar = function() {
$http.get("http://localhost/wsRest/index.php/contato"
).success(function (response) {
loadLista.contatos.data = response;
});
};
}])
.service('loadLista', function() {
var lista = {
contatos: {},
};
return lista;
});
// view:
<ul>
<li ng-repeat="contato in contatos.data">
{{ contato }}
</li>
</ul>
I'm trying to share data between 2 controllers that are on 2 different pages, but it's not working as expected.
page1.html:
<form ng-controller="FormController">
<input ng-model="user.email">
</form>
page1controller.js:
app.controller("FormController", ['$scope', '$http', '$window', 'UserEmailService', function($scope, $http, $window, UserEmailService) {
// Code logic here
console.log($scope.user.email) // Code outputs a string here
UserEmailService.setEmail($scope.user.email);
$window.location.href = "/page2"; // Redirects to page2.html after logic completes
}]);
page2.html:
<div controller="SomeController">
<p> Hi, your e-mail is {{ email }} </p>
</div>
SomeController.js:
app.controller("SomeController", ['$scope', 'UserEmailService', function($scope, UserEmailService) {
console.log(UserEmailService.getEmail()); // outputs undefined
$scope.email = UserEmailService.getEmail();
}]);
UserEmailService.js
app.service("UserEmailService", function(){
var email = [];
var setEmail = function(val) {
email.push(val);
};
var getEmail = function() {
return email.pop();
};
return {
setEmail : setEmail,
getEmail : getEmail
};
});
I'm trying to get the user e-mail from page1.html and displaying it on page2.html, but it always comes up as undefined on page2.html. What am I doing wrong?
In FormController, $window.location.href will cause a full page reload, which make your service state reset. Try $location.url('') to navigate to that route. It does not cause a full page reload.
If you want your data available after a full page reload. You should use something like localstorage instead.
Use factory instead of service. For more information angular.service vs angular.factory
app.factory("UserEmailService", function(){
var email = [];
var setEmail = function(val) {
email.push(val);
};
var getEmail = function() {
return email.pop();
};
return {
setEmail : setEmail,
getEmail : getEmail
};
});
In your listening controller (SomeController)
$scope.$watch(function () {
return UserEmailService.getEmail();
},
function (newValue, oldValue) {
if (newValue !== oldValue){
$scope.user.email = newValue;
}
});
So that your final code looks like
app.controller("SomeController", ['$scope', 'UserEmailService', function($scope, UserEmailService) {
$scope.$watch(function () { return UserEmailService.getEmail();},
function (newValue, oldValue) {
if (newValue !== oldValue){
$scope.user.email = newValue;
}
});
}]);
EDIT - lots of changes
After my page loads, I have some javascript function calls that return data which will be used in my markup to populate tag options.
Currently the issue is this: When the values are changed by the javascript outside ( and even inside the AngularJS controller). The view is not being updated. I have tried wrapping scope assignments in $scope.$apply(...) however this just results in a $digest() already in progress error.
AngularJS Code:
app.service('userService', ['$http', function($http) {
var userModel = {
qGroupZero: '',
qGroupOne: '',
qGroupTwo: ''
};
var states = '';
return{
getUserModel: function() {
return userModel;
},
getStates: function() {
return states;
},
loadChallengeQuestions: function() {
var userEnrollmentChallenge = getChallengeQuestions();
console.log('loadChallengeQuestions()');
userModel.qGroupZero = userEnrollmentChallenge.challengeQuestions.questionGroup[0];
userModel.qGroupOne = userEnrollmentChallenge.challengeQuestions.questionGroup[1];
userModel.qGroupTwo = userEnrollmentChallenge.challengeQuestions.questionGroup[2];
},
loadStates: function(callback) {
console.log('loadStates()');
return $http.get('content/states.json').then(function(result) {
states = result.data;
});
}
};
}]);
app.controller('EnrollmentController', ['$scope', 'userService', '$http', function($scope, userService, $http) { //Dependencies and Constructor function.
$scope.userService = userService;
$scope.states = [];
userService.loadChallengeQuestions();
var userModel = userService.getUserModel();
$scope.qGroupZero = userModel.qGroupZero.challengeQuestion; //<-- This assignment is not updated in the view.
userService.loadStates().then(function(result) {
$scope.states = userService.getStates(); //<-- This assignment is not updated in the view.
});
}]);
The content of challengeQuestion is a JSON array of 7 items.
The Markup:
<select ng-model="selectionOne"
name="question1"
ng-options="opt as opt.questionText for opt in qGroupZero">
</select>
<select ng-model="state"
name="state"
ng-options="opt as opt.abbreviation for opt in states"
class="required">
</select>
So at this point. I have all my resources. And I just need to find a way to get AngularJS to re-evaluate the ng-options value (a $scope.value) and redraw the content? I think I'm saying that right...
Why do I feel that this should be easy? And yet three days later here I am :D
Thanks for reading and helping!!!
What if you use the angular $http service and promise objects instead?
app.service('userService', ['$http', function($http) {
var userModel: {
qGroupZero: '',
qGroupOne: '',
qGroupTwo: ''
};
var states = '';
return{
getUserModel: function(){
return userModel;
},
getStates: function(){
return states;
},
loadChallengeQuestions: function(userEnrollmentChallenge) {
console.log('loadChallengeQuestions()');
userModel.qGroupZero = userEnrollmentChallenge.challengeQuestions.questionGroup[0];
userModel.qGroupOne = userEnrollmentChallenge.challengeQuestions.questionGroup[1];
userModel.qGroupTwo = userEnrollmentChallenge.challengeQuestions.questionGroup[2];
},
loadStates: function(){
return $http.get('content/states.json').then(function(result){
states = result.data;
});
}
}
});
app.controller('EnrollmentController', ['$scope', 'userService', function($scope, userService) { //Dependencies and Constructor function.
$scope.states = [];
userService.loadStates().then(function(result){
var userModel = userService.getUserModel();
$scope.states = userService.getStates();
$scope.qGroupZero = userModel.qGroupZero.challengeQuestion;
});
}]);