Function stops to work when $http is inside it - angularjs

I've got a pretty odd issue if I ask myself.
Currently I've got a function in my view which is something like this:
<h3 ng-click="{{ vm.open(item.info) }}"> {{ item.title }} </h3>
and a function in my controller looking like this:
open = (url) => {
console.log(url);
}
This function works as intended it writes out the slug of the item from the view. But the issue comes when I try to add my API service or a simple $http.get() call. It seems to break the entire function because if I add this to the function:
open = (url) => {
console.log(url);
result.getOpportunity(url).then(result => {
res = result.data;
var modal = res.title;
console.log(modal);
});
}
Nothing gets printed out in the console. not even the first console.log() that worked so pretty just seconds ago.
Can anyone tell me what is going on? I don't get any error in either console or terminal but something do seem to be broken somewhere.
Worth mentioning is that I'm using an yeoman generator called Angular fullstack which uses Babel.
If I look into my gulp serve:ed .controller.js file that when I use the function that works. the single console.log line my file contains this:
this.open = function (url) {
console.log(url);
};
and when I use the longer function which doesn't work this is in the ouputted controller.js:
on the line where the function that works was this is now: _initialiseProps.call(this); and later on this function:
var _initialiseProps = function _initialiseProps() {
var _this2 = this;
this.open = function (url) {
console.log(url);
_this2.result.getOpportunity(url).then(function (result) {
res = result.data;
var modal = res.title;
console.log(modal);
});
};
};
so Babel rewrites pretty much. but the most peculiar thing I noticed was that if I call _initialiseProps.call(this); explicit via the console I get returned undefined which do make some sense because the function _intiliaseProps() function does not contain a function called call()
but when I call _initialiseProps(this); from the console I get an error returned with this:
post.controller.js:29 Uncaught TypeError: Cannot set property '_checkURLforHTTP' of undefined(…)
Which is kinda funny or i dont know.. tearing my hair right now. Anyway, the _checkURLforHTTP function contains this in the code before babel had it's thing going:
_checkURLforHTTP = (img) => {
if (img.indexOf('http://') > -1 || img.indexOf('https://') > -1 ) {
return 'url("' + img + '")';
} else {
return 'url("http://HARDCODED-URL-HERE' + img + '")';
}
};
and the same function in the babel-processed file is the following:
var _initialiseProps = function _initialiseProps() {
var _this2 = this;
this._checkURLforHTTP = function (img) {
if (img.indexOf('http://') > -1 || img.indexOf('https://') > -1) {
return 'url("' + img + '")';
} else {
return 'url("https://HARDCODED-URL-HERE/' + img + '")';
}
};
};
Obviously it is something i'm not doing right, but i dont seem to understand what it is im doing wrong. I think I've managed to break it down into a click function in the view using $http.get();

Related

React: Method finishing before data loaded

I am trying to retrieve some data from Yahoo Finance using an XHTML Request, which works. However, I am trying to display the data retrieved on my app, but the method to retrieve the data is returning "undefined" before the data has been loaded.
async componentDidMount() {
var tempData = await this.fetchAsync();
console.log(tempData)
this.handleLoad(tempData)
}
handleLoad = (num) => {
this.setState(state => ({
price: num
}));
}
async fetchAsync () {
const xhr = new XMLHttpRequest();
xhr.withCredentials = true;
const {params} = this.props.navigation.state;
var ticker = params.ticker;
var result;
var tempArray = [1];
var url = "https://yahoo-finance-low-latency.p.rapidapi.com/v8/finance/spark?symbols=" + ticker + "&range=2y&interval=1d"
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
result = JSON.parse(this.responseText);
tempArray = result[ticker]['close'];
testPrice = tempArray[tempArray.length-1]
console.log(testPrice)
var self = this;
return tempArray[tempArray.length-1]
}
});
xhr.open('get', url, true);
xhr.setRequestHeader("x-rapidapi-key", "my key");
xhr.setRequestHeader("x-rapidapi-host", "yahoo-finance-low-latency.p.rapidapi.com");
xhr.send();
}
I am using the componentDidMount() function to begin calling the methods to load the data, but when the app renders, the values are not displayed.
As you can see inside the fetchAsync() method, I return the value I need, but when I try and console.log the return from this method, I get undefined.
I have also tried moving this return to the end of the method, but when I use console.log here to ensure that tempArray has the data I need, it is empty.
I need to display tempArray[tempArray.length-1] on my screen, but the data is not loaded in time, and does not update even after it has loaded.
Your return tempArray[tempArray.length-1] inside the fetchAsync isn't actually returning from fetchAsync -- it's just returning from the callback function inside addEventListener. In fact, you don't actually have any code that is taking advantage of the async tag you have on that function.
One solution to this would be to call handleLoad directly from inside fetchAsync instead of return tempArray. (Of course, you'll want to make sure that you've bound this correctly to handleLoad).
Another solution would be to pass a callback function into fetchAsync that you could call instead of returning. Then, at your call site, it might look something like this:
this.fetchAsync((tempData) => {
console.log(tempData)
this.handleLoad(tempData)
});
Finally, a third solution would be to switch from XMLHTTPRequest to fetch, and then you could take advantage of async/await and actually make that fetchAsync method async (and be able to return a value from it).

Can't read folder from firebase storage bucket

I'm new to both react and firebase. I'm trying to get a string of file names (just as a continuous string for right now) from a particular folder in the firebase storage bucket. My code is as follows:
getFilesList(){
var toReturn="";
toReturn+="Testing";
var storage = firebase.app().storage(".....");
var storageRef = storage.ref();
var listRef = storageRef.child("/slides/1HdDPbTarLBxzllDlA3H/Lecture1/");
listRef.listAll().then(function(result) {
result.items.forEach(function(imageRef) {
toReturn+=this.getImageString(imageRef);
});
}).catch(function(error) {
toReturn+="error1";
});
return toReturn;
}
getImageString(imageRef) {
var toReturn="T1";
imageRef.getDownloadURL().then(function(url) {
var toReturn=url.toString();
}).catch(function(error) {
toReturn+="error2";
});
return toReturn;
}
I'm not getting any errors, but the return string is blank (aside from the 'Testing' prefix). The folder has about 20 jpg files, but it seems as though it isn't seeing that they are there. I did some research online about it, but I'm still not sure why my code isn't working. Please help me to know why this isn't working?
Thank you,
Jared
This isn't a problem with your framework, it's a problem with asynchronous code.
See, toReturn will eventually update with the results of that function call. The problem is that the caller of this function receives the array immediately, before any of the code in .then has a chance to touch it.
Even if the promise resolves instantly, the code above it will have already executed. Promises get put on a queue where the top item only executes after the current synchronous code has finished.
What getFilesList needs to do is return a Promise that the caller can then attach to in order to specify its own behaviour:
getFilesList(){
var toReturn="";
toReturn+="Testing";
var storage = firebase.app().storage(".....");
var storageRef = storage.ref();
var listRef = storageRef.child("/slides/1HdDPbTarLBxzllDlA3H/Lecture1/");
listRef.listAll().then(function(result) {
result.items.forEach(function(imageRef) {
toReturn+=this.getImageString(imageRef);
});
return toReturn;
}).catch(function(error) {
toReturn+="error1";
return toReturn;
});
And in the caller:
getFilesList.then(filesList => console.log(filesList))

call on function returns undefined on first call

In my controller i am calling this function in my service. idservice.getid()
I am testing it by printing it to console using console.log(idservice.getid())
and it returns undefined the first time, but after that if i call it again it returns the value.
I understand this is a async issue but im not sure how to make this work.
my service is below:
function idservice (userauth) {
var id;
this.getid = function() {
userauth.currentUser().then(function(user) {
id = user.id;
});
return id
}
}
How can i make it so that on the first call it doesnt return undefined? Is this a async issue?
This's happening because inside userauth currentUser() method you're making http call and response ('user.id') is yet not available. You can return the userauth.currentUser() call inside getid() method & also return id inside its success callback then. So your service method should look like
function idservice (userauth) {
var id;
this.getid = function() {
return userauth.currentUser().then(function(user) {
id = user.id;
return id;
});
}
}
And inside controller you should handle it like
idservice.getid().then(function(response){
$scope.id = response;
});
Here's small example of your requirement: https://plnkr.co/edit/bEjR9e179aRPfJiaQpei?p=preview
I've encountered this problem today, seems like if you request some data from the server and you assign it to a variable THEN you try to print it, it will show undefined on the first call, I think this is not something it should happen since you are trying to print it AFTER you got the information, but whatever.
I fixed it by removing that variable, just got the data then printed it.
I think this will solve your problem (the OP's last login is 2 years ago, but maybe it will help somebody else that encountered this and didn't found a useful answer?)
function idservice (userauth) {
this.getid = function() {
return userauth.currentUser().then(function(user) {
return user.id;
});
}
}
This will return the user.id as it is, it will not store it in a variable, you want it to be stored in a variable ? Store it, but don't print that variable, something like this :
function idservice (userauth) {
var id;
this.getid = function() {
return userauth.currentUser().then(function(user) {
id = user.id;
return user.id;
});
}
}
This worked for me (or at least the logic behind it worked).

AngularJS $.post code runs after rest code

I have created following function in AngularJS
var enq_dt = new Date();
$.post("/api/EMSAPI/EnquiryDetails?enq_no="+o_enq_no, null, function (returnedData) {
enq_dt = returnedData["D_O_O"];
console.log("Loading Post Block");
console.log(enq_dt);
});
console.log("Loading General Block ");
console.log(enq_dt);
$scope.CurrentQuotation = {
EnquiryNo:o_enq_no,
EnquiryDate: enq_dt,
QuotationBy:"TEST"
};
I am getting following result in console window.
Loading General Block
2010-11-26T00:00:00
Loading Post Block
2010-12-12T00:00:00
I want to Load Post block first and after that I want to run General Block.
What I am missing (I am new to Angular) ?
Thanks in advance.
I suggest you Google the word "asynchronous". In JavaScript, things like HTTP requests are almost always asynchronous.
To get your general code to run after the post, call it with .then():
function generalCode() {
console.log("Loading General Block ");
console.log(enq_dt);
$scope.CurrentQuotation = {
EnquiryNo:o_enq_no,
EnquiryDate: enq_dt,
QuotationBy:"TEST"
};
}
var enq_dt = new Date();
$.post("/api/EMSAPI/EnquiryDetails?enq_no="+o_enq_no, null)
.then(function (returnedData) {
enq_dt = returnedData["D_O_O"];
console.log("Loading Post Block");
console.log(enq_dt);
})
.then(generalCode);

Updated to angularfire 0.8 resulted in a TypeError

I followed along Thinksters tutorial about firebase and angularjs
It worked great but I wanted to use the new functionality of $asArray() which required an update of angularfire (0.8).
Somehow this results in different TypeError (TypeError: undefined is not a function). For instanc on:
var query = $firebase(ref.startAt(authUser.uid).endAt(authUser.uid));
query.$on('loaded', function () { //ERROR LINE
setCurrentUser(query.$getIndex()[0]);
and
findByUsername: function (username) {
if (username) {
return users.$child(username); //ERROR LINE
}
}
I'm still able to sign in which means that i have connetction with Firebase. Does anybody have an idea of what went wrong or if I have to update anything more to get this working again?
EDIT:
my setCurrentUser-method:
function setCurrentUser (username) {
$rootScope.currentUser = User.findByUsername(username);
}
I've made an attempt to change my findByUsername-method:
findByUsername: function (username) {
if (username) {
return (users.$getRecord(username));
}
}
(relates to)
var ref = new Firebase(FIREBASE_URL + 'users');
var users = $firebase(ref).$asArray();
Still don't know a good way to search through my firebase-array correctly without .$child(username). Do I need a loop?

Resources