Ok, one of the first things I see there, and likely the reason you are not seeing any console.log entries, is that you are assigning $scope.tasks to be a function, but you are not executing that function.
In Javascript, you can assign a variable to be a function. If you do that, two things do not happen:
- the function does not automatically get executed
- even when it does get executed, the return value from that function does not become the new value of the variable, the variable is still the function
For instance:
var myThing = function () {
var something = getTheThing();
return something;
}
All that does is say that myThing is a function waiting to be executed. It doesn't actually run until you do
myThing();
And, even after you do that, myThing does not suddenly have the value of the returned something. Even after you execute it, myThing is still a function, that you could execute again by calling myThing() again. In order to get that returned value something, you would have to do
// you have to execute the function, and then assign
// the return value to another variable
var theRealThing = myThing();
So going back to your code example, when you do
$scope.tasks = function () {
// stuff with console.logs in it
return something;
}
it does not execute immediately. In order to see the console.logs, you would have to then do
$scope.tasks();
If you execute the function like that, you will start to see your console.logs, however, remember that the return value from that function does not then become the value of $scope.tasks, it will still be the function you defined it as.
My guess is that you do not actually want $scope.tasks to be a function, what you want it to be is the tasks from the project. You are getting close with how you are chaining your functions that make the two async REST calls, you just need a little bit more to handle both responses and pass that data back to where you need it.
[Before we go any further, I'd just like to point out that I have never used Angular, so I am not 100% familiar with $http or how Angular scoping works. So I am making some assumptions here, but my code example may not work exactly as I am intending because of things I don't know about how Angular works.]
I would suggest using a Promise that you create yourself (not the ones automatically created by $http) so that you can control exactly when that Promise resolves, so that you can make sure you have all the data together at the time you resolve the Promise.
Also, I would make a few adjustments to the code to make things a little more logical and readable, for instance, your function setPropertyId does not actually set anything, it uses the project ID you got in the previous function to then get the tasks for that project. It might be more appropriate to name that function getTasks, since that's what it does. Also, you pass the full response object from getPropertyID into that function, and then make that function (setPropertyID aka getTasks) deal with the response from getPropertyID. It would make more sense for the success handler for getPropertyID to deal with the response it receives and peel the ID off it. Then, if getTasks needs a project ID in order for it to work, then pass only the project ID into it. It will make it much more clear as to what that function needs to work and what it actually does.
So here is an example of how I would set up what you are trying to do (again, with the caveat that I don't know Angular, so it's untested and might not work exactly as is, but you should see the general idea):
//controller for late tasks
app.controller('tasksController', function ($scope, $http) {
function getPropertyID() {
return $http({
method: 'GET',
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/allProperties?$select=MSPWAPROJUID",
headers: { "Accept": "application/json; odata=verbose" }
})
}
function getTasksFromProject(projectId) {
return $http({
method: 'GET',
url: _spPageContextInfo.webAbsoluteUrl + "/_api/ProjectData/Projects(guid'" + projectId + "')/Tasks",
headers: { "Accept": "application/json; odata=verbose" }
})
}
function getProjectIdAndTasks () {
// return a Promise from this function so that _you_
// can control when it resolves, since you want this
// whole process to wait for both the request to get the ID
// _and_ the request to get the tasks
return new Promise(function (resolve, reject) {
getPropertyID()
.then(function (projIdResponse) {
// don't just pass the full response on to the next function,
// deal with it here and get the data you want from it so
// it's more clear what data you are getting from where
var ProjectUID = projIdResponse.d.MSPWAPROJUID;
console.log('got the project id:', ProjectUID);
// now just pass what the next function actually needs
// (the project id) on to the next function
getTasksFromProject(ProjectUID).success(function (tasksResponse) {
// the 'length' property of the results array is really just the count,
// it's not the actual tasks themselves
var numberOfTasks = data.d.results.length;
// the actual tasks themselves are in the 'results' array
var tasks = data.d.results;
console.log('got the tasks:', tasks);
// resolve the outer promise with a custom object
// that has both the project ID and the tasks
resolve({
projectId: ProjectUID,
projectTasks: tasks
});
}).error(function (error) {
console.log(error);
// reject the outer promise because there was an error
reject(error);
})
})
});
}
// set off the whole process, and then once you get the result from
// your resolved promise, you can set that data where you want it
getProjectIdAndTasks().then(function (bothResults) {
console.log('got both project ID and tasks:', bothResults);
// now that you have all the data you want from the server,
// assign it where you want it
$scope.tasks = bothResults.projectTasks;
$scope.projectId = bothResults.projectId;
}).catch(function (error) {
console.log('could not get project ID and tasks:');
console.log(error);
})
})
For more info on Promises, look here. And if you are new to Javascript and want to learn more about how it works, I highly recommend the eBook series "You Don't Know JS".