Can not print data from API request - javascript

I am trying to learn working with API calls and responses and I needed a basic value that comes from api response but I wasn't able to get it work. So here is my problem;
(function worker() {
$.get('URL', function(data) {
$('#numbers').html(data); });
})();
I use this code and this works perfectly fine, and writes the API response to my HTML page. Also the API calls return the value in this format;
{
"success":"true",
"field1": {"number1":"number1_val","number2":"number2_val"},
"field2": {"number11":"number11_val","number22":"number22_val"}
}
Now, I tried to write the values from API response and I was successfull for writing the "success" value like this;
$('#success_val').html(data.success);
It printed true value to my HTML website in given #success_val field. However, when I tried to write the field1, or the first value of field1, I wasn't successful. I tried
$('#numbers').html(data.field1); => No success, empty page
$('nu#mbers').html(data.field1[0]); => No success, empty page
So, at this point, what I need to store & use is the "number11" value from field 2. I have read and searched for over an hour and found out that this api return is not a valid "array" return, instead it is called "field" (I might be wrong), but I couldn't find any info about how can I get the "number11" data from this api response.

$('#numbers').html(data.field1); => No success, empty page
Does data.field1 exist for sure? or spelling check.
you can get keys by Object.keys(data).
If exist data, it return ["success", "filed2", "field2"].
In the same way, you already know key, like number11,
data.field2.number11 or data["field2"]["number11"] return value.
If you don't know key, data["filed2"][Object.keys(data)[0]] return value

Thanks to https://stackoverflow.com/users/10366589/sh-k I have solved the problem in given way;
As I wasn't able to print output from field2 to HTML, I have checked keys at field2 with this code;
alert(Object.keys(data.field2));
and it returned
number11,number22
since I only needed number11 from that API response, I did the following;
var.storednumber = Object.keys(data.field2);
var.storednumber = storednumber[0];
$('#numbers').html(storednumber);
and I was able to get the number I wanted printed on the screen without any problem :)
There could be a better solution or fix for the issue I am having, but for now, this has solved. I guess the problem lies on the API response type as it doesn't return an array formatted data.

Related

Call a specific array in a JSON API call

I'm trying to call the API but it doesn't return me anything.
I'm calling it like: res.on('data', d => { const RetrieveFromApi = JSON.parse(d).FLUX.quote.USD.price;.
The API is successfully called since I can see it in the API history, and data is defined as d.
Can you help me please?
from your screen provided in comment, you passed one property you don't access to it which is data
So just add property data before FLUX
JSON.parse(d).FLUX.quote.USD.price;
^data.FLUX.quote.USD.price;
From the image of the log the object seems incomplete at the end, did you try to use JSON.stringify(d) to see if there are any errors on the json object? or copy the response on https://jsonlint.com to check?
Because the error message points that the parse doesn't find a valid json object, maybe that is the whole point.
And the other tip is to try to store the value of JSON.parse in an variable before trying to access his values.

Dialogflow: Is this being used in an async call

I'm new to the javascript world and have been tinkering with Actions on Google. I had an action that was previously running but after attempting to simplify my code, I've been running into a new error I cannot seem to figure out. The code is supposed to make a call to a database and return information to the user based on the date they have selected.
Problem:
The code is supposed to make a call to a database and return information to the user based on the date they have selected. The intent seems to break down when I call the URL using axios. When I test my function I receive the following error from the Google Cloud Platform: "Error: No response has been set. Is this being used in an async call that was not returned as a promise to the intent handler?"
app.intent('Moon', (conv, {date}) => {
// Sets date to today if none given
if (!date) {
date = new Date().toISOString();
}
// Slices date string to match date format in database
const dateSlice = date.slice(5, 9);
// Call to row in dabase for the given date
function getData() {
return axios.get(`example.com/search?Date=${dateSlice}`);
}
return getData().then(res => {
res.data.map(con => {
conv.ask(`On X date there will be a ${con.Object1}`);
});
});
});
I don't know much about Promise and await but that seems to be the issue. I'm not sure how I was able to get my code to run before without these objects. I've tried to insert a Promise object before my return but it makes the rest of the function unreachable. I also checked to see if Axios had any updates but it has not, I am on the latest version. Does the error have to do with one of the returns perhaps?
It could be related to Promises, but you seem to be handling them correctly.
The call to axios.get() is returning a Promise...
... which you are returning in getData()...
... which is returned in the 'Moon' Intent handler as part of the getData().then() block.
I suspect more that this is a logic problem. If res.data is an empty array, then there will be no calls to conv.ask(), so you end up not asking anything.
There is also a problem if res.data has more than two items. In this case, you'll generate an error because you've replied with more than two "simple" responses.
Either way - you may wish to log res and/or res.data to make sure you're getting back what you think.

Parse Server Upset Data in loop

I'm trying to query an API to get some data then I want to upsert all of it into my table.
But for some reason I'm not having any luck.
What's the best way to go about this?
I don't think my method of doing a query in a loop is best.
var coin = new Parse.Object.extend("Coins");
axios.get('https://api.coinmarketcap.com/v1/ticker/')
.then(response => {
let data = response.data;
// Put into database
data.map(entry => {
let q = new Parse.Query(Model.Coins.className());
q.equalTo('symbol', entry.symbol);
q.first()
.then(record => {
record.set('symbol', entry.symbol);
record.set('price_usd', entry.price_usd);
return record.save(null, {useMasterKey: true});
});
});
res.success(response);
});
you should avoid fetching and updating objects in a loop. In order to make it better you need to use 2 things:
In your query, instead of using equalTo and first you need to use containedIn for query all the records in one call. Then you need to iterate on the query results, for each record in the loop you need to do the following:
record.set('symbol', entry.symbol);
record.set('price_usd', entry.price_usd);
Finally you need to use saveAll to save all the objects in one call (please notice that saveAll is static function of Parse.Object and you should pass an array into it. Please review the docs before doing it)
Check your data. You may find you have unexpectedly updated records.
Assuming that's the entire body of a cloud function, your function initiates an asynchronous server call, then immediately tells the requestor that the operation was successful, but response isn't populated yet so you pass back undefined. However, parse-server will still run that asynchronous code.
The solution is to put the res.success call inside another .then chain, so the function won't return a response until after the server call + save finishes.
You're also going to get an uncaught error if the symbol doesn't exist on your table, though. You don't check to make sure the query returned a response to the first() call.

JavaScript - Promise fulfilled too early?

I created a small sample application using VueJs and created a C# REST API to store and retrieve data in a SQL Server back end.
For testing, I created a simple web page with a form to create a "note". The note is stored by the following function, 'saveData()':
saveData()
{
let promiseStack = [];
var jsondata = JSON.stringify(this.note);
promiseStack.push(this.$http.post('REST_API/note', jsondata));
Promise.all(promiseStack).then(data =>
{
this.$http.get('REST_API/note');
this.$router.push({ name: 'viewnotes', params: { id: data[0].body.id }})
}, error =>
{
console.log(error);
});
}
I tried to use a promise to wait until the 'store' operation in the backend is complete, and issue a GET request to retrieve all notes once the promise is fulfilled.
However, the get request inside the promise doesn't return any data. If I issue the get request manually later one, I retrieve the data that was stored previously.
So I had look into the C# REST API. There are currently two functions: createNote(...), getAllNotes(...). I used a StreamWriter to log to the filesystem when these functions are called, using milisecond precision. What I see is that 'createNote' is called after 'getAllNotes'. So I suspect that the API is working correctly, but something with the way I'm using promises seems to be awfully wrong.
Maybe somebody has a hint?
UPDATE
I know that the GET request doesn't return any data by using the developer toolbar in Chromium. The response is empty
The developer toolbar in the network tab shows that the requests are submitted in the correct order, so the "POST" request is issued first
It seems I found the problem. I had a 'href' tag in my 'Save' link, which triggered an early routing. The intended 'POST' and 'GET' were fired correctly, but there was another 'GET' inbetween somewhere because of the 'href' tag in the link, even though it was empty.
I removed the tag, now it works as intended.

jQuery Deferred returns only last value in loop

So I'm trying to go through one Firebase database to find entries in the database matching a criteria. Therefore I'm using the deferred object of jQuery to handle the database calls.
Once I get a return value from this first database I want to get the user info from a second database for each of those values in the first db. Then the results are added to a JSON array
so its:
<search for value, find one>
<<<search other db for oher info>>>
<continue search for outer value>
But this only returns one value - although everything else is running fine (and the console logs all the info correct).
Here's the code:
function find(searchLocation, profileID) {
var requestUserData = {
data: []
};
var def = $.Deferred();
//This will be executed as long as there are elements in the database that match the criteria and that haven't been loaded yet (so it's a simple loop)
Ref.orderByChild("location").equalTo(searchLocation).on("child_added", function(snapshot) {
def.ressolve(snapshot.val().ID);
});
return def.promise();
};
I hope you guys have any ideas on what to do or how I could solve this. Thanks in advance!
Edit: upon further testing I discovered that this problem already exists in the outer loop - so only the first value is being returned. I think this is related to the posission of the resolve() method but I didn't find a posibility on how to change this behaviour.
Firebase is a real-time database. The events stream as changes occur at the server. You're attempting to take this real-time model and force it into CRUD strategy and do a GET operation on the data. A better solution would be to simply update the values in real-time as they are modified.
See AngularFire, ReactFire, or BackboneFire for an example of how you can do this with your favorite bindings framework.
To directly answer the question, if you want to retrieve a static snapshot of the data, you want to use once() callback with a value event, not a real-time stream from child_added:
Ref.orderByChild("location").equalTo(searchLocation).once("value", function(snapshot) {
def.resolve(snapshot.val());
});

Categories

Resources