Skipping undefined elements from an API call - javascript

I am gathering data from an API to show the Pokemon typing. Some Pokemon have one type, while others have two.
The variables to gather the typing data are as such.
function createPokemonCard(pokemon) {
const type = pokemon.types[0].type.name;
const second_type = pokemon.types[1].type.name;
...}
And then I call them via InnerHTML in the same function with the following code.
<small class="type"><span>${type}/${second_type}</span></small>
Predictably, when it hits undefined for a Pokemon, it breaks and doesn't display the card. However I am not sure how to get it to not print the second type when it's undefined.
I thought about doing an if statement, but what should I call if there is an undefined variable?
function undefined {
if(second_type === 'undefined') {
???
}}
Or would a for loop work better? I am not sure how to get it to bypass the undefined and print nothing.

const second_type = pokemon.types[1] ? pokemon.types[1].type.name: undefined;
`<small class="type"><span>${type}${second_type!=undefined ? `/${second_type}`: ''}</span></small>`
The ? : syntax is a ternary operator (mdn)
It's a less verbose way of writing out the following:
if (second_type!=undefined) { // check if second_type is not undefined
return `/${second_type}` // if it's not return / and the second type
} else { //otherwise
return '' // return an empty string
}

If you do not want to display the trailing / when second_type is not defined one way to go could be
const type = pokemon.types.map(({ type }) => type.name).join("/")
and then
<small class="type"><span>${type}</span></small>

Related

What does the syntax x:y mean in JavaScript?

I am following a course on blockchain which has the following piece of code.
What does " index:this.chain.length+1 " mean? Is index a variable in the object newBlock? Or is it a key value pair? If it is a variable, why don't we simply use index=this.chain.length+1? Also what is the type of the object newBlock?
function Blockchain()
{
this.chain=[];
this.newTranscations=[];
}
Blockchain.prototype.createNeBlock = function(nonce,previousBlockHash,hash)
{
const newBlock ={
index:this.chain.length+1,
timestamp:Date.now(),
// all of the transactions in this block will be the transactions that waiting to be put in a block
transactions:this.newTranscations,
// nonce is hust a number giving proof of the transaction
nonce:nonce,
hash:hash,
previousBlockHash: previousBlockHash
}
// As we move all the pending transactions to the new block, we clear this array
this.newTranscations=[];
this.chain.push(newBlock);
return newBlock;
}
var Box = {
"playdoh":{"playdoh":["none", "some", "none", "none", "some"]}
};
Box of playdoh upon playdoh, you're getting into the study of Objects/Arrays/Maps.
To call the above out, it'd be
console.log(Box["playdoh"]["playdoh"][0]);
= none
console.log(Box["playdoh"]["playdoh"][4]);
= some
console.log(Box["playdoh"]["playdoh"][5]);
= null (undefined)
is the same as
console.log(Box.playdoh.playdoh[0]);
= none
console.log(Box.playdoh.playdoh[4]);
= some
console.log(Box.playdoh.playdoh[5]);
= null (undefined)
It is one of several ways to initialize an object called newBlock in javascript. Take a look at this documentation on MDN
The index property is of type number in this case, and it is set to equal chain[].length + 1

Understanding procedures in Snowflake (javascript)

I came through lately following line of code while analyzing 3rd party data script.
CREATE OR REPLACE PROCEDURE WH.SCHEMA.PROCEDURE_NAME(DATE_OF_LOAD STRING) --input which will be binded later
RETURNS STRING
LANGUAGE javascript
AS $$
var drop_table = `drop table if exists TABLE_NAME;`;
var stmt_drop_table = snowflake.createStatement( {sqlText: drop_table} );
var incremental_data =
`CREATE TABLE AS <many arguments>
WHERE P.CZAS_MODYF_SF >= :1 --this is where biding of DATE_OF_LOAD occurs)
SELECT *, HASH(*) HASH FROM (
SELECT <arguments>
FROM CTE) q; `;
var stmt_incremental_data = snowflake.createStatement( {sqlText: incremental_data,binds: [DATE_OF_LOAD ].map(function(x){return x === undefined ? null : x}) } );
try {
stmt_drop_table.execute();
stmt_incremental_data.execute();
rtr = "Success!";
return rtr;
}
catch (err) {
return "Failed: " + err;
}
$$
;
Entire challenge I have is with:
var stmt_incremental_data = snowflake.createStatement( {sqlText: incremental_data,binds: [DATE_OF_LOAD ].map(function(x){return x === undefined ? null : x}) } ).
object.method part is clear. Same for binds. Code after binds is my issue here.
Another topic: Snowflake interpretes method's parameters as a JSON. Does it mean that bind value can be extended by assigning JS code?
I'll be greatly thankful for help and explanation.
The reason I did not post this as an answer initially is that JavaScript is not my area of expertise. I did dabble in it for a few months.
But in order to understand what is going on with:
[DATE_OF_LOAD ].map(function(x){return x === undefined ? null : x})
You need to break it down:
x === undefined ? null : x
This is called an elvis operator and is the equivalent of :
if (x === undefined)
{
return null
} else {
return x
}
Now that we know what the function does, we need to understand the map method. But in short it creates a new array with the results of calling a provided function on every element in the calling array.
So the simple answer copied from my comment is:
if DATE_OF_LOAD is undefined it will replace it with null, otherwise it will use whatever value is stored in DATE_OF_LOAD. That is because SQL does not know how to handle undefined.
But here is the reasoning for my answer.

Postman get variable used in array find doesn't work

Using the newest version of Postman.
I have a predefined variable "useridToken" which is a number: 123456
var useridToken = pm.environment.get("useridToken");
//console.log(useridToken);
var jsonData = pm.response.json();
const user = jsonData.find(u => u.user_metadata.employeeId === useridToken);
const userid = user ? user.user_id : 'not found';
pm.environment.set("user_id", userid);
Whenever I run this code, it returns errors.
The console log output is the number as an integer: 123456
Whenever I run the following code:
var useridToken = 123456
var jsonData = pm.response.json();
const user = jsonData.find(u => u.user_metadata.employeeId === useridToken);
const userid = user ? user.user_id : 'not found';
pm.environment.set("user_id", userid);
It works like a charm, but I don't want the hardcoded useridToken in my code, I would like to get it from my environment variables. I don't quite understand why the first part isn't working? What am I overseeing?
This is happening because in your .find method you're using === comparison, and when you fetch from environment you always get it as a 'string' and not a 'number' (Postman always gives the value of the environment variable in the string format)
So when you use a === comparison in JS, it also checks the type of the data, here
string === number will actually be false and that's why your find doesn't work.
So, you need to update your code to actually parse the integer that you got from the environment.
This should fix your issue:
var useridToken = parseInt(pm.environment.get("useridToken"));
SOLUTION:
Since you are using === operator, it checks for the type of the variables too. The type for both operands might be different on certain scenarios. So, use the following to avoid the issue.
const user = jsonData.find(u => +u.user_metadata.employeeId === +useridToken); // converts to number then checks
or
const user = jsonData.find(u => u.user_metadata.employeeId.toString() === useridToken.toString()); // converts to string then checks
or
const user = jsonData.find(u => u.user_metadata.employeeId == useridToken); // checks without the operands type. (not recommended)

Cannot read property 'toLowerCase' of undefined Angular 5

I am trying to filter a column of a ngx-table I follow the the example but it keeps giving that error "Cannot read property 'toLowerCase' of undefined"
here's the template part
<ngx-datatable-column name="Nom" class="name">
<ng-template ngx-datatable-cell-template let-value="value">
{{value}}
</ng-template>
</ngx-datatable-column>
and the function attached to it
updateFilter(event) {
const val = event.target.value.toLowerCase();
// filter the data
const temp = this.temp.filter(function(d) {
return d.name.toLowerCase().indexOf(val) !== -1 || !val;
});
// update the rows
this.rows = temp;
// Whenever the filter changes, always go back to the first page
this.table.offset = 0;}
Any idea of how to solve this?
It would appear that the the items being filtered through do not all contain a value 'name' within them. Try console.log(d) before your return within that function to verify you are receiving the data you expect.
It appears that your name property must be undefined in some cases. This could be that it is not the correct property name (is it lastName instead of name?) or that for some objects in the temp array that the value is undefined. In either case, you can check for a null first before returning the value.
if (d.name) {
return d.name.toLowerCase().indexOf(val) !== -1 || !val;
} else {
return null;
}

Function to conditionally assign variable member data to nested array in object?

I want to add data into an object, and my object contains nested data. Example data:
pageviewEvent {
client: "clientName",
page {
document_referrer: 'some http refer header data goes here',
window_height: 1920,
window_width: 1200
}
}
Some data is undefined or null and I do not want to add this undefined/null data into the object.
I made a function that works to add data to the object conditionally (if not undefined) but I can't figure out how to add data to nested objects in the function?
I could just make a bunch of if statements, but figure it's better to put the condition test into a function to reduce code size.
Example code with comment showing thinking of what I am trying but doesn't work:
//function to check if variable undefined or null, if not -> add to pageviewEvent arrayKey, variableName
function isUndefinedNull(arrayKey, variableName) {
var evalVariableName = eval(variableName);
if (evalVariableName !== undefined && evalVariableName !== null && evalVariableName !== "") {
console.log(arrayKey);
console.log(variableName);
pageviewEvent[arrayKey] = evalVariableName;
//array key could be nested, for instance pageview[page][title] or pageview.page.tile
}
}
//make event array
const pageviewEvent = { }
//add static data
pageviewEvent.client = 'neguse';
//if not null or undefined add data
isUndefinedNull('referrer.full', 'document.referrer');
//want to put data into object pageviewEvent.referrer.full or pageviewEvent[referrer][full]
Thanks for any help. I feel like this answer can help but I can't figure it out.
I recommend using the lodash function _.set(), documentation can be found here: https://lodash.com/docs/4.17.4#set
_.set( pageviewEvent, "referrer.full", "some-value" );
If you want to customise the behaviour of how nesting is handled when there's an undefined value, you can instead use _.setWith() - see https://lodash.com/docs/4.17.4#setWith

Categories