Previous array data gets printed to string - javascript

this is related to the code from my previous question, but this new problem is related to printing array data into a string, which then is passed on to the text on my page
My page "rolls" genetic data, which is presented as gene abbreviations. Under the abbreviations, i want to list the gene names. What happens is that the array values from a previous "roll" gets printed underneath a new roll, meaning that the array that contains the gene names is always one "roll" behind.
i suspect it has to do with the fact that im using $.getJSON, but I'm not sure how to use the current data instead of the previous data.
here is what my code for this part looks like:
$.getJSON('genes.json', function(data){
$.each(data.gCommon, function(i, g) {
if(genoArray.includes(g.rec) || genoArray.includes(g.dom)){
phenoArray.push(g.phen);
}
});
getPheno(phenoArray);
});
function getPheno(phenoArray){
console.log(genoArray);
console.log(phenoArray);
$phenoString = phenoArray.join(", ");
}
$babyGenes = genoArray.join("/");
if(genoArray.length > 1){
$babyPheno = $phenoString.replace(/("[^"]+"|\w+)$/, "and $1");
} else {
$babyPheno = $phenoString;
}
console.log("Baby: " + $babyGenes);
console.log("Pheno: " + $babyPheno);
any advice helps, thanks in advance!!

Related

Trouble getting a specific field from OpenWeatherMap API's output, via JS / XMLHttpRequest

So I'm building this web forecast app using OpenWeatherMap API, and so far I'm being able to fetch the data from the first iteration of the list's output, however I need to obtain the data of other specific fields aswell. Here's a bit of my code:
ajaxGet("https://api.openweathermap.org/data/2.5/onecall?lat=4.6097&lon=-74.0817&exclude=current,minutely,hourly,alerts&appid=APPID&units=metric", function (response) {
var data = JSON.parse(response);
console.log(data);
var temperature = document.createElement("h6");
temperature.textContent = data.daily[0].temp.max + "°" + " / " + data.daily[0].temp.min + "°";
document.getElementById("temperaturaBogVier").appendChild(temperature);
});
And here's an example of what the API's output looks like (I'm only showing the first iteration in here, but there are at least 6 in total, https://api.openweathermap.org/data/2.5/onecall?lat=4.6097&lon=-74.0817&exclude=current,minutely,hourly,alerts&appid=APPID&units=metric):
{"lat":4.61,"lon":-74.08,"timezone":"America/Bogota","timezone_offset":-18000,"daily":
[
{"dt":1600876800,
"sunrise":1600857917,
"sunset":1600901504,
"temp":{"day":18.14,"min":8.99,"max":18.14,"night":12.08,"eve":15.45,"morn":8.99},
"feels_like":{"day":17,"night":11.02,"eve":14.6,"morn":7.58},
"pressure":1017,"humidity":54,
"dew_point":8.69,
"wind_speed":1.2,
"wind_deg":164,
"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}],
"clouds":82,
"pop":0.94,
"rain":5.85,
"uvi":15.14}
]
}
So as you can see, I'm being able to print into my HTML the data contained into "data.daily[0].temp.", but it only works for the first set of fields and I got no clue how to select a specific iteration. I'm sure I'm missing something into the concat, but nothing I've tried has worked so far.
Any help would be greatly appreciated, and rewarded with an imaginary waffle. THX :D
The temperatures for each day data.daily are defined as an JavaScript array of objects. You can simply access them by their index, which indicates their position in the array.
data.daily[0] // First element
data.daily[1] // Second element
data.daily[2] // Third element
Once you have selected an object within the array, you can then access certain values like data.daily[2].temp.max.
The cool thing about arrays is that you can iterate them with a loop. This will save you a lot of writing, if you want to print out each temperatures for every day:
ajaxGet("https://api.openweathermap.org/data/2.5/onecall?lat=4.6097&lon=-74.0817&exclude=current,minutely,hourly,alerts&appid=YOUR_API_KEY_HERE&units=metric", function (response) {
var data = JSON.parse(response);
console.log(data);
data.daily.forEach(function (date) {
var temperature = document.createElement("h6");
temperature.textContent = date.temp.max + "°" + " / " + date.temp.min + "°";
document.getElementById("temperaturaBogVier").appendChild(temperature);
})
});
Please note: I've removed the appid=XXXXX part of the request URL, because it contains your personal API key for OpenWeather, which you should not share publicly.
If I understand the question correctly, you want to take all daily max/min-values and put them into elements that you want to append to another element.
Here is a way to do that
ajaxGet("https://api.openweathermap.org/data/2.5/onecall?lat=4.6097&lon=-74.0817&exclude=current,minutely,hourly,alerts&units=metric", function (response) {
var data = JSON.parse(response);
console.log(data);
data.daily
.map(datapoint => datapoint.temp) //get the temp value/object from each datapoint
.map(temp => { //create an element and add each max/min value to that element's textContent
const temperature = document.createElement("h6");
temperature.textContent = temp.max + "° / " + temp.min + "°";
return temperature;
})
.forEach(element => { //add each of the elements created in the previous map to the desired element
document.getElementById("temperaturaBogVier").appendChild(element);
});
});
As pointed out in the other answer, I've also removed the app-id query parameter

resolving a javascript and database table logic situation

When I query a database table, I get back values "yes" or "no" for records that represent whether an item is present or not (the item is the column name). I want to create a string that represents the products that are available by name (rather than what I am doing now "kitchen table =" + kitchenTable;
I am thinking this can be solved (poorly) by a series of if statements setting variables to either the product name or to "" and then include all variables in the string
var kt;
if (kitchenTable == yes) kt = "kitchen table";
else kt = "";
if (kitchenCabinet == yes) kc = "kitchen cabinet";
else ka = "";
output = kt + ', ' + kc;
There are about 50 items that can be presented to the user, is there a more efficient way of accomplishing this task?? One option is to change how values are entered into the datbase table such that instead of yes, its the item name but this seems like a poorer way to resolve the issue
Of course you don't give all the details about how do you make query so that is an imaginary mockup of a function simulating query
var available = [];
var result = query("kitchen table");
result === "yes" && ( available.push("kitchen table") );
......
var output = available.join();
What you want is actually built into javascript itself.
I would say using an object literal will really simply your life in this situation by organizing your code and turning it into a more readable format.
I would also recommend turning your server data into true and false as this is a standardized way to communicated a Boolean and allows for the method below to work as it does:
// From server response
var results = {
kitchenCabinet: true,
kitchenTable: true
}
// Use this for your storage of all related items
var kitchenProps = {
kitchenCabinet: 'kitchen cabinet',
kitchenTable: 'kitchen table'
}
// Reuse this function for each time your need a new category (masterBathroomProps...)
function getItemDataIfExists(results, hashTable){
'use strict';
var output = 'Your total is: ';
for (var item in results) {
if (!results.hasOwnProperty(item)) return;
if (results[item]) output += 'A '+hashTable[item]+' ';
}
return output;
}
getItemDataIfExists(results, kitchenProps);
Explanation:
You loop through a result set of an object containing keys names and true false values. In the loop, if the keyname's value is true, then use that keyname to access the properties (in this case a string of your choice. The "key" here is that the key names in each object must line up.
Here is a live demo:
http://codepen.io/nicholasabrams/pen/JXXbYz?editors=0010

CasperJS each then next (future) value of response array

im using eachThen() method of CasperJS and I need to know the value of the next iteration item.
I have items like this :
array = [
[22,"blah"],
[22,"blah"],
[23,"blah"],
[24,"blah"],
[24,"blah"],
[24,"blah"]
]
I'm generating one file per group of items (grouped by [0]) .
My first approach was to compare the actual item with the previous item at the beginning of the iteration , and if [0] is different generate the file, like this :
//previousItem was initilizated = to actualItem
casper.eachThen(array , function (response) {
var actualItem = response.data
casper.then(function(){
if(actualItem[0] != previousItem[0]){
var filename = previousItem[0]+"file.html"
var f = fs.open(filename, 'a');
f.write(stdFile);
f.close();
previous = actualItem
}
});
//operations that prepares stdFile to be created
Problem appears at the end of the cycle, as im comparing actual with previous, the last group will not generate any files (of course, the 2 last items will have the same [0], and after that the cycle will end)
My solution here is to ask for the next item instead of the previous, and generate the file at the end of each iteration , but I dont know how to tell Casper to give me the item of actualItem+1 in the array.
I will try to fix this iterating the same array inside in paralel and returning the value of actual+1 , but maybe there is a way to do it using response variable.
The result must be 3 files : 22file.html , 23file.html and 24file.html
There are a lot of requests to make
, so I need to win any second I can.
If you have another approach to achieve this please let me know.
PS: Sorry for my english, its not my native language
Thanks
My first approach was too complicated, probably because I didnt sleep so much these days.
This is what I did :
cajIndex = 0;
//this block generates the file if actualItem (or actualCajero is the same) is not undefined and the actualItem[0] is not the same as the next item
if (actualCajero != undefined)
{
if (actualCajero[0] != cajerosArray[cajIndex][0]){
casper.then(function(){
var filename = "Ventas local"+" "+nombreLocal+"_"+actualDay[1]+"-"+actualDay[2]
stdFile = '<h1>'+filename+'</h1> <table border="1">'+ stdTable + '</table>';
this.echo("generando archivo "+filename);
var f = fs.open(filename+".xls", 'a');
f.write(stdFile);
f.close();
stdTable = "";
stdFile = "";
});
}
}
//after this i do my operations , ask again for file creating at the end but now if the next item is undefined, if it is undefined creates the file then
cajIndex++
and that solves everything, the key was declaring that index at 0 and asking for file creating before assigning actualItem to response, and then ask again at the end for the last item.
Hope it helps

Cannot save object props to parse.com table

I have a form with a textbox title, dropdown menu year and a button. When I click the button, I want to get the values of title and year as properties to an object Movie. Then save them to a table on parse.com. The code below adds a recording to the table with values undefined.
<script>
function saveValues() { // function is appended as onclick to button
var $titleValue = $('#inputTitle').val();
var $select = $('#select');
var $yearValue = $select.val();
var Movie = Parse.Object.extend("Movie");
var movie = new Movie();
// movie.set('title', $titleValue); // Doesn't work. Returns undefined
// movie.set('year', $yearValue); // Doesn't work. Returns undefined
movie.title = $titleValue; // Works
movie.year = $yearValue; // Works
alert(movie.title); // Returns the value
alert(movie.year); // Returns the value
alert(movie); // Returns [object Object]. I was expecting {title: '<SOMETITLE>', year: '<SOMEYEAR>'}
console.log(movie); // This prints a lot of stuff and title and year are there with the respective values.
movie.save()
.then(function(object) {
alert("yay! it worked");
})
}
</script>
Note that when I try to save only the title to the table, it works fine.
Without seeing your full code, I can't guarantee that this will work, but give this a try:
movie.save({
title : $titleValue,
year : $yearValue,
}, {
success: function(movie) {
alert("movie saved successfully with title: " + movie.get("title") +
", and year: " + movie.get("year"));
},
error: function(error) {
alert("error, movie save failed. error code: " + error.code + ", " error.message);
}
});
At the very least you will have a descriptive error message that will tell you what went wrong. Based on the fact that you said it works when you only save the title and not the year, I suspect it may be because your 'year' field in Parse is stored as a number, but you are passing it in as a string (since it came from an HTML form, I'm assuming).
If that doesn't work, I also suspect it may have something to do with appending this function to your button onload rather than as a click or a submit. But that wouldn't explain why it still works if you just leave out the year.
Finally, I wonder if Parse's SDK is confused by the '$' symbol at the beginning of your variable names, but I don't see why that would be the case.
OK, after some time I found out what the problem was. And it was a silly one. It turns out that the value in option was of type 'string'. By adding parseInt() like so: var $yearValue = parseInt($select.val());. And then movie.save({title: titleValue, year: yearValue})..... This way everything works. Initially, I had tried putting key-value pairs in the save() but the year value wasn't the right type.
So note to anyone out there - check your data types!

How to encode cookie with javascript/jquery?

I am working on an online shop together with my friend. He set a cookie for me with PHP with the amount of added products to the Cart. The cookie is called "cart", and the variable with the amount of the products is called "items".
And I have to read the cookie and get the value of "cart" back with javascript and print it in the HTML document, but I have no Idea how to use it, can you please help me? I have never worked with cookies or JSON before, but I think it should be done with JSON, can you please explain it to me how it works?
when I do : console.log(document.cookie);
I receive something like this: cart=%7B%22items%22%3A%7B%228%22%3A1%7D%7D;
And I have no idea how to encode it.
Thank you
That is the URL encoded equivalent of {"items":{"8":1}} which is the JSON string you want.
All you have to do is decode it and parse the JSON:
var cart = JSON.parse(decodeURIComponent(document.cookie.cart));
Then logging cart should give you an object with an 'items' property that you can access as needed.
EDIT:
As an example, here's a way to iterate through the items and determine the total number of items and the total of all their quantities.
var items_total = 0,
quantity_total = 0;
for (var prop in cart.items) {
items_total += 1;
quantity_total += cart.items[prop];
}
console.log("Total Items: " + items_total);
console.log("Total Quantities: " + quantity_total);
Looks like you just need to decode it, then you will want to parse/eval it to get a workable object:
var obj, decoded = decodeURIComponent(document.cookie.cart);
if(window.JSON && JSON.parse){
obj = JSON.parse(decoded);
} else {
eval('obj = ' + decoded);
}
// obj == {"items":{"8":1}};

Categories

Resources