Okay, I have three relevant files for my question/s..
App.js - app.config
In my app.config passing value in the resolve using $stateParams is possible and I attain it. But how about the value is from the controller? I need the provCode value to use it in my php select query.
.state("editStudent", {
abstract: true,
url:"/student/:id",
controller: "EditStudentController",
templateUrl: "views/students/editStudent.html",
resolve: {
dataservice: 'dataservice',
student: function(dataservice, $stateParams){
var data ={
id : $stateParams.id
};
return dataservice.getStudent(data);
},
provinceData: function(dataservice){
return dataservice.getProvince();
},
municipalityData: function(dataservice){
var provCode = {
provCode : '0456' // <--------------------- this one
}
return dataservice.getCity(provCode);
}
}
})
EditStudentController.js - app.controller
In my app.controller, I use the angular.forEach to find province code or id to use it php select query. As you can see I tried to create function app.getCity but it is not working as I expected.
console.log(provinceData);
$scope.provinceData = provinceData;
var retProv = $scope.studentInfo.province;
angular.forEach(provinceData, function(value, key) {
if(value.provDesc == retProv){
$scope.studentInfo.province = provinceData[key];
$scope.provCode = provinceData[key].provCode;
console.log($scope.provCode);
}
}); // angular.forEach
var provCode = $scope.provCode;
// Test if it is working but sadly, it is not
// $scope.getCity = function(){
// dataservice.getCity(provCode);
// }
Dataservice.js - app.factory
In my app.factory there are currently 3 functions. The other 2 functions works expectedly but the factory.getCity() is my problem right now. As you can see there is a parameter provCode, this parameter is from my app.config state resolve and it has been assigned a hardcoded/static value.
factory.getStudent = function(data){
return $http.post("php/students/viewOneStudent.php",data).then(function(response){
student = response.data[0];
console.log(student);
return student;
})
}
factory.getProvince = function(){
return $http.get('php/address/province.php').then(function(response){
provinceData = response.data;
console.log(provinceData);
return provinceData;
})
}
factory.getCity = function(provCode){
return $http.post('php/address/cities.php', provCode).then(function(response){
municipalityData = response.data;
console.log(municipalityData);
return municipalityData;
})
}
My Question is:
If it is possible to pass a value from controller to a resolve?
If it is possible, how can I do that? because I tried my very best in trial and error approach.
If it is not possible, what is my option/s to achieve what I want?
Note
I tried to do it without resolve, getting data and posting again for php querying, it is also works BUT the problem is sometimes data doesn't load when the view is loaded. As far as I know, read and understand from different sources in the internet, there is a time that view is loaded but the "work on processing the data" is not finished yet..
I am pretty new and still learning AngularJs. When I am practicing and learning AngularJs coding, I love how it works especially the routing, I am impressed with it. So, I am trying my very best to understand AngularJs and its complexity.
UPDATE
I tried different approach of how I can get my expected results. But I can't get to it, I encountered an error. This is the link of my other approach.
Undefined property: stdClass: in using AngularJS + PHP
Related
I have an angular project. I am making an html/angular form - getting the data from a stored procedure via $http get in a service in angular. Now I want to databind some of the drop down lists in my filter that's in this html form. I have the data in a view which I made models for and added to the entity framework. How should I make calls to this breeze in angular? Code example please? in service or in controller?
------here's what i've tried--------------
what am I doing wrong here? (may be a few things...i'm new to angular. Then I just want to be able to somehow call this function populatestyleddl in my ng-model or something....
.factory('sellingService', ['$filter', '$http', function ($filter, $http) {
function PopulateStyleDDL() {
return breeze.EntityQuery.fromEntityNavigation('v_Style')
.using(context.manager).execute();
};
//check if above function is legal
function SalesStatus(filter) {
console.log(breeze);
return $http({
method: 'GET',
url: '/Services/SalesStatus',
params: { filter.itemStyle }
}).then(function (result)
{ return result.data; })
}
return {
SalesStatus: SalesStatus
};
}]);
--------------------------------here's what i have now.....
ok, here is what i've got now. this is happening in a js file where all my breeze calls are. Can you confirm if my syntax here is right and how my function syntaxically should look in my factory (and also how my syntax should look in my controller...)
function GetStyles() { return breeze.EntityQuery .from("v_Style") .using(manager) .execute(); }
#LisaSolomon, regarding your syntax:
function GetStyles() {
return breeze.EntityQuery
.from("v_Style")
.using(manager)
.execute();
}
Looks good with the information I have. If it's not working I'd make sure:
The controller has a properly-defined v_Style action, and
The manager is defined and has the correct service name
So, assuming that is correct, you will need to add it to your returned object so that it is available in your controller:
return {
SalesStatus: SalesStatus,
GetStyles: GetStyles
};
Then to use it in your controller, you will need to reference the .then() of the promise
$scope.styles = '';
sellingService.GetStyles().then(function(data) {
$scope.styles = data.results;
}).catch(function(err) {
// error processing
});
Any error messages you're getting would be helpful. If there's any chance you could show controller and view code so we could build a fiddle, that would be great, too.
I'm creating an hybrid app with Ionic that will load some JSON files that are stored on the device. Since the same data will be used in several different states, I thought it would make sense to store the response to the JSON request and reuse it, rather than re-reading the JSON file over and over.
This question seems to address that scenario, but I can't seem to get it to work. Although the template works when I used a simpler $http.get().success() request, it never fills in since I started trying to use this service.
app.factory('localJsonService', function($http, $q) {
var localJsonService = {};
localJsonService.returnLegislators = function() {
if (this.legislators) {
return $q.when(this.legislators);
}
return $http.get('/data/legislators.json').then(function(response) {
this.legislators = response.data;
return this.legislators;
});
}
return localJsonService;
});
//old malfunctioning controller
app.controller('profileController', function($scope, $stateParams, localJsonService) {
$scope.legislators = localJsonService.returnLegislators();
$scope.legislator = $scope.legislators[$stateParams.seq_no-1];
console.log($scope.legislator); //displays undefined
});
//EDIT: newer, working controller (but still loads JSON file on each new state)
app.controller('profileController2', function($scope, $stateParams, localJsonService) {
localJsonService.getLegislators().then(function(legislators){
$scope.legislator = legislators[$stateParams.seq_no-1];
});
});
Is it just a simple change to the service that I'm missing? Or am I going about this the wrong way entirely? I'm running AngularJS v1.3.13, but I'm not opposed to a different version, if that will help.
Thanks for any help you can give me.
Use a promise callback and assign your variables in that callback:
localJsonService.returnLegislators().then(function(legislators){
$scope.legislators = legislators;
$scope.legislator = legislators[$stateParams.seq_no-1];
console.log($scope.legislator);
});
If the service data response is not changing, I'd rather user localStorage to cache your response. I'll suggest you ngStorage, that makes it really easy to use localStorage and sessionStorage.
P.S: if datas are changing, then use sessionStorage, that is persistant upon session, but cleaned after app restart.
Example after injecting $localStorage:
Set a default value :
var jsonDefaultVariable = {};
jsonDefaultVariable["myDatas"] = false;
$localStorage.$default(jsonDefaultVariable);
Check for cache :
if($localStorage["myDatas"] !== false){
factory.myDatas = $localStorage.myDatas;
}else{
$http(....).success(function(data){
$localStorage.myDatas = data;
factory.myDatas = data;
});
I am trying to figure out how to do a simple CRUD with angular + firebase. I started with a read operation. I have the following data structure:
Given that, I created the following rules:
I have a working factory as follows:
factory('wordsFactory', function($http){
var factory = {};
var words = [
{content:"hi", definition:"ooo"},
{content:"h3", definition:"ooo222"}
];
factory.getWords = function(){
return words;
//ajax call here
};
factory.addWords = function(){
//something
}
return factory;
})
I modified it to try and include the call like so:
factory('wordsFactory', function($http){
var factory = {};
var words = [];
var ref = new Firebase('https://my-firebase.firebaseio.com/words');
ref.once('value', function($scope, snapshot) {
$scope.variable = snapshot.val();
words = [
{content: ref.content, definition: ref.definition}
];
});
factory.getWords = function(){
return words;
//ajax call here
};
factory.addWords = function(){
//something
}
return factory;
})
However, whenever I try to read I get:
Error: permission_denied: Client doesn't have permission to access the desired data.
and
FIREBASE WARNING: Exception was thrown by user callback. TypeError: Cannot read property 'val' of undefined
A number of things, I realize that because of the way I have it, even if it worked, it would only return 1 value. I'm ok with that right now since I just want to figure out how to make it work. I also know that my current data structure could be greatly improved, again I just did it to learn but feel free to suggest anything you think might help me.
My chief concern right now is that I can't get it to read. I should also mention that the factory works properly without firebase, it's being called in the main controller.
I think your issue is related to RULES.
Try replacing the default RULES to below:
{
"rules": {
".read": true,
".write": true
}
}
Now you can access without any Errors.
I'm not sure how you came to this construct:
ref.once('value', function($scope, snapshot) {
But the once callback only takes a single argument for the value event. See the relevant Firebase API documentation.
So you'll have to change it to:
ref.once('value', function(snapshot) {
And find another way to get the scope in there.
For troubleshooting the failing read operation, I recommend using the simulator tab in your Firebase dashboard. It will typically show you a better explanation of why the operation is rejected. This detailed information is intentionally not shown in the regular clients.
I've spent the night on trying to figure this out and have finally decided to give up and ask for help.
I'm building a web-app with AngularJS that is designed to work with flakey connections (mobiles).
I'm trying to implement the functionality for a user to add a object (whether that's an appointment, book, etc is irrelevant) to the server.
Service that handles syncing objects with the server:
angular.module('App')
.service('syncUp', function syncUp($http, $q, app) {
this.addObject = function addObject(object) {
var deferred = $q.defer();
app.inSync = false;
var httpConfig = {
method: 'POST',
url: 'http://myurl.dev/app_dev.php/api/add-object',
data: object
}
function persist() { setTimeout(function() {
$http(httpConfig).
success(function(data, status) {
app.inSync = true;
deferred.resolve(data.id);
}).
error(function(data, status) {
app.inSync = false;
persist();
});
}, 3000);
};
persist();
return deferred.promise;
}
});
'app' service that the status bar is bound to:
'use strict';
angular.module('App')
.service('app', function app($http, $q) {
this.inSync = true;
});
Template binding to the 'app' service inSync property:
<div class="status" ng-class="{'insync':inSync}"></div>
Specific object service that sends data from the controller to the syncUp service:
this.addBook = function(book)
{
var tempId = syncUp.generateUid();
this.books[tempId] = book;
this.books[tempId].tempId = tempId;
syncUp.addObject({
'type': 'book',
'data': this.books[tempId]
}).then(function(newId) {
booksRef[newId] = book;
delete booksRef[tempId];
}, function() {});
}
Everything is working as it should (data is being persisted to the server and the ID is being returned and replacing the tempId just fine. The problem is, when the inSync key on the 'app' service is updated, the class isn't added/removed from the div as it should be with ng-class in the template. If I load another route, that will force iterate through whatever internal cycle angular is doing and update the class on the template.
I've tried all manner of $apply() solutions, moving where the app.inSync key is set back to true, looping a function watching it. It's being set in all the right places (from debugging I know it's set back to true correctly), I just can't figure out how to make the change appear on the UI.
I tried:
$rootScope.$apply(function() {
app.inSync = true;
});
Which gave me an error (already running a digest, or something).
So I tried the 'safeApply' version that has been circulated on many answers/blogs, which didn't throw the error, but didn't work either.
As far as I can figure out, the UI should be updated when promises are resolved (both the http and my syncUp.addObject promise are resolved, so I'm not sure why it's not working.
Any ideas? I need to keep the current implementation of promises to be able to set the returned ID from the server on the added object, to avoid a circular-dependency issue between the syncUp and object angular services.
Edit:
And the status bar directive:
angular.module('App')
.directive('navigation', function (app) {
return {
templateUrl: '/app/views/navigation.html',
restrict: 'E',
link: function (scope, element, attrs) {
scope.inSync = app.inSync;
}
}
});
References you make in templates refer to objects on the current $scope. Services do usually not create or add anything to the $scope, so putting properties on a service, will not make them available to the template. To get stuff on the $scope, you need to use a controller. You can use the ng-controller directive to reference a controller, you'll find examples of this in the first AngularJS tutorials.
What you should do is create a controller and have it listen for events from the service. Here's an example of how to do that.
That's the nice way; You might also be able to get away with it by putting the inSync = true on the $rootScope as such;
service('syncUp', function syncUp($http, $q, app, $rootScope) {
// (...)
$rootScope.inSync = true;
It looks like you're hoping to see bindings operating between a service ('app') and a template. It's hard to tell if we're not seeing the entire picture. Going on that assumption, you need to refactor so that you are setting up bindings on a controller.
I would expect the controller setup to look something like this:
angular.module('App')
.controller('app', function app($http, $q, $scope) {
$scope.inSync = true;
});
Now you will have two-way binding hooked-up on the 'inSync' property.
Otherwise, your template looks fine.
If I'm off base, please update your question with more context, or better yet make a fiddle to boil down the problem.
I am trying to do something more abstract with Resolve but failing to get the output. Looks like I am missing something.
Problem : I need to load the lookup table data before the view loads. So, I am using resolve in ui-router which is working great for each lookup. I thought its better to make a collection of lookups into a single object but its failing. Here is the code.
Not working code:
resolve: {
lookups: ['GenericFactory', function(genericFactory) {
return {
StateList: genericFactory.GetStateList().then(function(response){return response.data;}),
EmployeeTypeList: genericFactory.GetEmployeeType().then(function(response){return response.data;})
}
}]
}
Working code:
resolve: {
StateList: ['GenericFactory', function(genericFactory) {
return genericFactory.GetStateList()
}],
EmployeeTypeList: ['GenericFactory', function(genericFactory) {
return genericFactory.GetEmployeeType()
}]
}
From the docs:
An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved before the controller is instantiated.
I'd say you can't make the non-working code work that way since you are trying to return an object. Since the object is not a promise by itself, the rule above does not apply.
Maybe this will work - you can fire up these requests, wrap them in a promise of its own and return that (haven't been tested):
lookups: ['$q', 'GenericFactory', function($q, genericFactory) {
var deferred = $q.defer();
var q1 = genericFactory.GetStateList().then(function(response){return response.data;}),
var q2 = genericFactory.GetEmployeeType().then(function(response){return response.data;})
$q.all([q1, q2]).then(function (res) {
var obj = {
StateList = res[0];
EmployeeTypeList = res[1];
}
deferred.resolve(obj);
});
return deferred.promise;
}]