i have an ion-slide component with 3 slides. when running the app the first time, all three slides load. however, going to another controller and coming back to the controller where the ion-slide is (using $state.go), only displays one slide and has the following error:
TypeError: Cannot read property '0' of undefined
seeing this error, i traced it passes through this line first:
sharedProperties.setProperty($scope.cardNumbers[$scope.currentIdx]
.CardNumber);
instead of this code fetching the card number:
var url = 'http://10.10.9.169/UserService3/WebService1.asmx';
$http.get(url + '/getCardsbyUsername' + '?unameID=' + currentID ).success(function(response) {
// stuff
console.log('response is jsonobj = ' + response);
var strObj = JSON.stringify(response).replace(/"(\w+)"\s*:/g, '$1:');
var myObject = eval('(' + strObj + ')');
$scope.cardNumbers = myObject;
console.log('response is jsonarr = ' + $scope.cardNumbers);
})
.error(function(response) {
// error stuff
console.log('response error is = ' + response);
});
here's the full code:
$scope.currentIdx = 0;
var currentID = sharedProperties3.getUserID();
console.log('current ID = ' + currentID);
var url = 'http://10.10.9.169/UserService3/WebService1.asmx';
$http.get(url + '/getCardsbyUsername' + '?unameID=' + currentID ).success(function(response) {
// stuff
console.log('response is jsonobj = ' + response);
var strObj = JSON.stringify(response).replace(/"(\w+)"\s*:/g, '$1:');
var myObject = eval('(' + strObj + ')');
$scope.cardNumbers = myObject;
console.log('response is jsonarr = ' + $scope.cardNumbers);
})
.error(function(response) {
// error stuff
console.log('response error is = ' + response);
});
$scope.options1 = {
initialSlide: 0,
onInit: function(slider1)
{
$scope.slider1 = slider1;
sharedProperties.setProperty($scope.cardNumbers[$scope.currentIdx].CardNumber);
},
onSlideChangeEnd: function(slider1)
{
console.log('The active index is ' + slider1.activeIndex);
$scope.currentIdx = slider1.activeIndex;
console.log('The active card is ' + $scope.cardNumbers[$scope.currentIdx].CardNumber);
sharedProperties.setProperty($scope.cardNumbers[$scope.currentIdx].CardNumber);
}
};
$scope.options2 = {
direction: 'vertical',
slidesPerView: '1',
pagination: false,
initialSlide: 1,
showNavButtons: false
};
how can i make it pass through the $http.get code block first?
i noticed i was loading angularjs more than once, so i got rid of the extra code calling angularjs in my index.html and it worked.
Related
Can anybody explain what im doing wrong here, my setState console is returning undefined where the first console is returning right values
return firebase.database().ref('Users/Trainers/').on('value', (snapshot) => {
snapshot.forEach(function(childSnapshot){
// var childKey= childSnapshot.key;
var childData= childSnapshot.val();
var childEmail = childData.email;
var childfirstName = childData.firstName;
var childlastName = childData.lastName;
var childTrainers = childfirstName + ' ' + childlastName + ' ' + childEmail;
console.log(childTrainers);
})
this.setState({
Trainers: snapshot.val().childTrainers
})
console.log(this.state.Trainers)
})
Okay ive done, and the correct answer is
return firebase.database().ref('Users/Trainers/').on('value', (snapshot) => {
snapshot.forEach((childSnapshot) => {
// this.setState({
// childEmail = childSnapshot.val().email
// })
// var childKey= childSnapshot.key;
var childData= childSnapshot.val();
var childEmail = childData.email;
var childfirstName = childData.firstName;
var childlastName = childData.lastName;
var childTrainers = childfirstName + ' ' + childlastName + ' ' + childEmail;
//console.log(childTrainers);
this.setState({
Trainers: [childTrainers]
}, console.log(this.state.Trainers))
})
})
All values are retrieving
I am new in Javascript and bit by bit I have used resources here on StackOverflow to build on a project that uses external API to get time entries for users from the 10k ft project management system. I have finally have different functions together as follows:
Calls for user details which includes user_id
Get the time entries and sums up for every user who's approval has a value (pending or approval) in a specific date range. Those without approval will be ignored in the summation and their total entries left at 0.
My challenge now is to have only those with 0 as total hours of time entries receive emails to update their time entries. This code doesn't seem to select only those with 0 and send emails specifically to them. I will appreciate any pointers and/or assistance. after sending the email, this should be recorded on Google sheet
var TKF_URL = 'https://api.10000ft.com/api/v1/';
var TKF_AUTH = 'auth'
var TKF_PGSZ = 2500
var from = '2020-01-20'
var to = '2020-01-26'
var options = {
method: 'get',
headers: {
Authorization: 'Bearer ' + TKF_AUTH
}
};
function getUsers() {
var userarray = [];
var lastpage = false;
var page = 1;
do {
// gets 10kft data
var users = read10k_users(page);
// writes data from current page to array
for (var i in users.data) {
var rec = {};
// pushing of mandatory data
rec.id = users.data[i].id;
rec.display_name = users.data[i].display_name;
rec.email = users.data[i].email;
userarray.push(rec);
}
// checks if this is the last page (indicated by paging next page link beeing null
if (users.paging.next != null) {
lastpage = false;
var page = page + 1;
} else {
lastpage = true;
}
}
while (lastpage == false);
return (userarray);
return (userarray);
}
function read10k_users(page) {
var endpoint = 'users?';
var url = TKF_URL + endpoint + 'per_page=' + TKF_PGSZ + '&auth=' + TKF_AUTH + '&page=' + page;
var response = UrlFetchApp.fetch(url, options);
var json = JSON.parse(response);
//Logger.log(json.data)
return (json);
}
function showTimeData() {
var users = getUsers()
var time_array = [];
for (var i = 0; i < users.length; i++) {
// Logger.log(users[i].id)
var url = 'https://api.10000ft.com/api/v1/users/' + users[i].id + '/time_entries?fields=approvals' + '&from=' + from + '&to=' + to + '&auth=' + TKF_AUTH + '&per_page=' + TKF_PGSZ;
var response = UrlFetchApp.fetch(url, options);
var info = JSON.parse(response.getContentText());
var content = info.data;
var total_hours = 0;
for (var j = 0; j < content.length; j++) {
if (content[j].approvals.data.length > 0) {
total_hours += content[j].hours;
}
}
Logger.log('User name: ' + users[i].display_name + ' ' + 'User id: ' + users[i].id + ' ' + 'total hours: ' + total_hours+ ' ' + 'Email: ' + users[i].email)
}
}
function sendMail(showTimeData){
var emailAddress = user.email;
var message = 'Dear ' + user.display_name + 'Please update your details in the system'
var subject = ' Reminder';
MailApp.sendEmail(emailAddress, subject, message);
}
I was able to get a solution for this as follows:
for (var j = 0; j < content.length; j++) {
if (content[j].approvals.data.length > 0) {
total_hours += content[j].hours;
}
}
Logger.log('User name: ' + users[i].display_name + ' ' + 'User id: ' + users[i].id + ' ' + 'total hours: ' + total_hours + ' ' + 'Email: ' + users[i].email)
if (total_hours == 0) {
sendMail(users[i])
}
}
}
function sendMail(user) {
var emailAddress = user.email;
var message = 'Dear ' + user.display_name + 'Please update your details in the system'
var subject = ' Reminder';
MailApp.sendEmail(emailAddress, subject, message);
}
I have my angularjs project, in this I have this code block, which is fired depending upon the dropdown selection. In this code the if and else part is mostly similar, I want to refactor the code so that the code is not repeated.
if (1 === $scope.form.type) {
response = $scope.resource.searchItemSalesInfo(params.get, params.post,function(response, headers) {
angular.forEach(response, function(row, id) {
response[id].prod_info = row.alias + ' (' + row.final_product_id + ') ';
});
$scope.totalCount = headers('x-total-count');
});
} else {
response = $scope.resource.searchOrderSalesInfo(params.get, params.post,function(response, headers) {
angular.forEach(response, function(row, id) {
response[id].prod_info = row.alias + ' (' + row.final_product_id + ') ';
});
$scope.totalCount = headers('x-total-count');
});
}
I tried to take the common functionality out in the below manner, but then the code does not works, and it breaks the functionality.
$scope.callresource = function(resourcename){
response = $scope.resource.resourcename(params.get, params.post,function(response, headers) {
angular.forEach(response, function(row, id) {
response[id].prod_info = row.alias + ' (' + row.final_product_id + ') ';
});
$scope.totalCount = headers('x-total-count');
});
}
if (1 === $scope.form.type) {
$scope.callresource(searchItemSalesInfo);
} else {
$scope.callresource(searchOrderSalesInfo);
}
Alternatively to my other reply, you could pass a reference to the function that you want to be executed in $scope.callresource ... in other words a callback function
I believe this is the more scalable approach.
$scope.callresource = function(resourceCallbackFunction){
response = resourceCallbackFunction(params.get, params.post,function(response, headers) {
angular.forEach(response, function(row, id) {
response[id].prod_info = row.alias + ' (' + row.final_product_id + ') ';
});
$scope.totalCount = headers('x-total-count');
});
}
if (1 === $scope.form.type) {
$scope.callresource($scope.resource.searchItemSalesInfo);
} else {
$scope.callresource($scope.resource.searchOrderSalesInfo);
}
You can't call the function using this syntax $scope.resource.resourcename because this syntax is telling JS to execute a function called resourcename.
Instead, try using the bracket notation:
$scope.resource[resourcename](..)
Also, when invoking the $scope.callresource function, pass the arguments as strings, because searchItemSalesInfo and searchOrderSalesInfo currently JS is trying to find them as variables.
$scope.callresource('searchItemSalesInfo');
Your code would look like this:
$scope.callresource = function(resourcename){
response = $scope.resource[resourcename](params.get, params.post,function(response, headers) {
angular.forEach(response, function(row, id) {
response[id].prod_info = row.alias + ' (' + row.final_product_id + ') ';
});
$scope.totalCount = headers('x-total-count');
});
}
if (1 === $scope.form.type) {
$scope.callresource('searchItemSalesInfo');
} else {
$scope.callresource('searchOrderSalesInfo');
}
I am using ngMock for unit testing and I need to use the $timeout.flush function in one of my tests, so I have added the two following lines to my test:
$timeout.flush();
$timeout.verifyNoPendingTasks();
as indicated on http://www.bradoncode.com/blog/2015/06/11/unit-testing-code-that-uses-timeout-angularjs/.
$timeout.flush() does flush the timeout as expected, however I am now getting an exception from angular-mocks.js every time I run my test:
LOG: 'Exception: ', Error{line: 1441, sourceURL: 'http://localhost:9876/base/node_modules/angular-mocks/angular-mocks.js?05a191adf8b7e3cfae1806d65efdbdb00a1742dd', stack: '$httpBackend#http://localhost:9876/base/node_modules/angular-mocks/angular-mocks.js?05a191adf8b7e3cfae1806d65efdbdb00a1742dd:1441:90
....
global code#http://localhost:9876/context.html:336:28'}, 'Cause: ', undefined
Does anyone know where this exception could come from? I get it as many times as I use the $timeout.flush() function.
Looking at the angular-mocks.js file, it looks like it comes from the $httpBackend function. I have tried to update the ngMock version but it does not change anything. I have tried version 1.4.7 (which is my angular version) and version 1.6.2.
function $httpBackend(method, url, data, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers) {
var xhr = new MockXhr(),
expectation = expectations[0],
wasExpected = false;
xhr.$$events = eventHandlers;
xhr.upload.$$events = uploadEventHandlers;
function prettyPrint(data) {
return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp)
? data
: angular.toJson(data);
}
function wrapResponse(wrapped) {
if (!$browser && timeout) {
if (timeout.then) {
timeout.then(handleTimeout);
} else {
$timeout(handleTimeout, timeout);
}
}
return handleResponse;
function handleResponse() {
var response = wrapped.response(method, url, data, headers, wrapped.params(url));
xhr.$$respHeaders = response[2];
callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(),
copy(response[3] || ''));
}
function handleTimeout() {
for (var i = 0, ii = responses.length; i < ii; i++) {
if (responses[i] === handleResponse) {
responses.splice(i, 1);
callback(-1, undefined, '');
break;
}
}
}
}
if (expectation && expectation.match(method, url)) {
if (!expectation.matchData(data)) {
throw new Error('Expected ' + expectation + ' with different data\n' +
'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data);
}
if (!expectation.matchHeaders(headers)) {
throw new Error('Expected ' + expectation + ' with different headers\n' +
'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' +
prettyPrint(headers));
}
expectations.shift();
if (expectation.response) {
responses.push(wrapResponse(expectation));
return;
}
wasExpected = true;
}
var i = -1, definition;
while ((definition = definitions[++i])) {
if (definition.match(method, url, data, headers || {})) {
if (definition.response) {
// if $browser specified, we do auto flush all requests
($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
} else if (definition.passThrough) {
originalHttpBackend(method, url, data, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers);
} else throw new Error('No response defined !');
return;
}
}
throw wasExpected ?
new Error('No response defined !') :
new Error('Unexpected request: ' + method + ' ' + url + '\n' +
(expectation ? 'Expected ' + expectation : 'No more request expected'));
}
have a some data one my page that is in a ng-repeat.
When the page and data 1st loads the data shows up.
When I move away from the page (using Angular Routing) make a change to the data (gets saved in db) then come back into the page (make call to db get new data) the ng-repeat data does not refresh. I can see the new data loading into the array and it is the new data.
I start the process on the page with
var sp = this;
sp.viewData = [];
sp.employee = [];
sp.ViewDataTwo = [];
$(document).ready(function () {
var testHeader = setInterval(function () { myTimer() }, 1000);
function myTimer() {
if (addHeaderToken() != undefined) {
clearInterval(testHeader);
sp.usageText = "";
if (sessionStorage.getItem(tokenKey) != null) {
sp.associatedInfo = JSON.parse(getassociatedInfo());
loadDataOne();
loadDataTwo();
}
}
}
});
I do this because I need to get my security toke from a JS script that I have no power over changes. So I need to make sure the code has ran to get me the token.
here are the functions I call..
function loadPasses() {
$http.defaults.headers.common.Authorization = "Bearer " + addHeaderToken();
$http.get('/api/Employee/xxx', { params: { employeeId: sp.employeeId } }).then(function (data) {
sp.viewData = data.data;
for (var i = 0; i < $scope. viewData.length; i++) {
sp.passes[i].sortDateDisplay = (data.data.status == "Active" ? data.data.DateStart + "-" + data.data[i].DateEnd : data.data[i].visitDate);
sp.passes[i].sortDate = (data.data[i].status == "Active" ? data.data[i].DateStart: data.data[i].visitDate);
}
});
}
function loadDataTwo () {
$http.defaults.headers.common.Authorization = "Bearer " + addHeaderToken();
if (sessionStorage.getItem(tokenKey) != null) $http.get('/api/Employee',
{
params: { employeeId: sp.employeeId }
}).then(function (data) {
sp.employee = data.data;
var tempPassString = "";
sp.ViewDataTwo = [];
var totalA = 0;
var totalU = 0;
for (var p = 0; p < sp.employee.dataX.length; p++) {
sp.ViewDataTwo.push(sp.employee.dataX[p].description + "(" + /** math to update description **// + ")");
totalA += parseInt(parseInt(sp.employee.dataX[p].Anumber));
totalU += parseInt(sp.employee.dataX[p].Bnumber));
}
sp.usageArr.push(" Total: " + totalA- totalU) + "/" + totalA + " Available");
//$scope.$apply();
});
}
One my view sp.viewData and sp.ViewDataTwo are both in ng-repeats.
Works well on load.. when I go out and come back in. I see the data reloading. But the view does not.
I have hacked the Dom to get it to work for now. But I would like to do it the right way..
Any help.
I have used
$scope.$apply();
But it tells me the digest is already in process;
the views are in a template..
Please help