I am self taught with Apps Script, so generally approach one problem at a time, as it comes up. Arrays are confusing!
I am using an API to get the number of social followers for Facebook, Twitter and Instagram accounts. Here is the code so far. Note I have removed the API call specifics for privacy, I have also used fake profile ID's in the above, for example 1111 = Facebook, 2222 = Twitter, etc...
var response = UrlFetchApp.fetch(endpointUrl, params);
var jsonss = JSON.parse(response.getContentText());
var dataset = jsonss.data;
Logger.log(dataset);
[{dimensions={customer_profile_id=1111, reporting_period.by(day)=2021-10-31}, metrics={lifetime_snapshot.followers_count=407919.0}}, {dimensions={reporting_period.by(day)=2021-10-31, customer_profile_id=2222}, metrics={lifetime_snapshot.followers_count=1037310.0}}, {dimensions={reporting_period.by(day)=2021-10-31, customer_profile_id=3333}, metrics={lifetime_snapshot.followers_count=806522.0}}]
then map the array -
var followers = dataset.map(function(ex){return [ex.dimensions,ex.metrics]});
Logger.log(followers);
[[{reporting_period.by(day)=2021-10-31, customer_profile_id=1111}, {lifetime_snapshot.followers_count=407919.0}], [{reporting_period.by(day)=2021-10-31, customer_profile_id=2222}, {lifetime_snapshot.followers_count=1037310.0}], [{customer_profile_id=3333, reporting_period.by(day)=2021-10-31}, {lifetime_snapshot.followers_count=806522.0}]]
Now I get stuck, I am not sure how to get 'followers_count' when 'profile_id=1111', can someone please help? I have tried using another map function ( var followers = dataset.map(function(ex){return [ex.dimensions.map(function(ex2){return [ex2.followers_count]}]}); ) however this doesn't work...
Any suggestions to push me in the right direction is very much appreciated!
If Logger.log(followers); is [[{reporting_period.by(day)=2021-10-31, customer_profile_id=1111}, {lifetime_snapshot.followers_count=407919.0}], [{reporting_period.by(day)=2021-10-31, customer_profile_id=2222}, {lifetime_snapshot.followers_count=1037310.0}], [{customer_profile_id=3333, reporting_period.by(day)=2021-10-31}, {lifetime_snapshot.followers_count=806522.0}]] and you want to retrieve the value of lifetime_snapshot.followers_count: 407919 by using customer_profile_id: 1111, how about the following sample script?
Sample script:
In this sample script, your values of followers is used.
const profile_id = 1111; // Please set customer_profile_id you want to use.
const res = followers.reduce((ar, [a, b]) => {
if (a["customer_profile_id"] == profile_id) {
ar.push(b["lifetime_snapshot.followers_count"]);
}
return ar;
}, []);
if (res.length == 0) return;
const followers_count = res[0];
console.log(followers_count);
When this script is used for your values of followers, I thought that 407919 is retrieved.
If the same IDs are existing, you can retrieve them using console.log(res).
Reference:
reduce()
Related
I'm working with an NBA API where one of the features is finding players by their last name.
The issue I have; is that multiple players can have the same last name, of course.
An example of the response from the API when sorting with last names:
"players": [
0: {
"firstName":"Anthony"
"lastName":"Davis"
"teamId":"17"
"yearsPro":"9"
"collegeName":"Kentucky"
"country":"USA"
"playerId":"126"
"dateOfBirth":"1993-03-11"
"affiliation":"Kentucky/USA"
"startNba":"2012"
"heightInMeters":"2.08"
"weightInKilograms":"114.8"
1: {
"firstName":"Deyonta"
"lastName":"Davis"
"teamId":"14"
"yearsPro":"3"
"collegeName":"Michigan State"
"country":"USA"
"playerId":"127"
"dateOfBirth":"1996-12-02"
"affiliation":"Michigan State/USA"
"startNba":"2016"
"heightInMeters":"2.11"
"weightInKilograms":"107.5"
}
I limited the results here, but it goes on and on, etc.
So, I am looking to do two things:
First, extract/filter the correct player using their first name and last name.
In said extraction, I still need the complete array information when it is matched.
So essentially, I want 'Deyonta Davis', but when found - I also need the rest of said player's information (years pro, college, country, etc.)
I already have a command set up to retrieve the first result of the nested data in this API via last name - where the command takes the last name you input and sends the first result. The precise problem is that the first result is likely not to be the guy you are looking for.
The goal is to include first & last name to avoid pulling the wrong player.
A snippet of how I currently call the information via last name:
// Calling API
const splitmsg = message.content.split(' ')
var lastnameurl = "https://api-nba-v1.p.rapidapi.com/players/lastName/" + splitmsg[1];
axios.get(lastnameurl, {
headers: {
"x-rapidapi-key": apikey,
"x-rapidapi-host": apihost
}
// Extracting Player Information (first result)
var playerfirstname = response.data.api.players[0].firstName;
var playerlastname = response.data.api.players[0].lastName;
var collegename = response.data.api.players[0].collegeName;
var countryname = response.data.api.players[0].country;
var playerDOB = response.data.api.players[0].dateOfBirth;
var yrspro = response.data.api.players[0].yearsPro;
var startednba = response.data.api.players[0].startNba;
Any help would be appreciated, thank you.
If I understand the question correctly the task is:
Retrieve first matching object from an array where properties firstName and lastName equal to desired values.
To achieve this you could use build in find function.
const player = array.find(el => {
return el.firstName === "Deyonta" && el.lastName === "Davis"
});
Keep in mind if there is no such object in array the player will be undefined.
I would like to receive a title and a link for 10 posts from Wordpress REST API.
My code is getting me only the first object in the JSON array. I'm aware that it's because [0], but I'm struggling with finding a solution to display desired values from all the objects.
<div class="mypanel">
<script>
$.getJSON('https://www.example.com/wp-json/wp/v2/posts', function(item) {
var text = `<li><h2>${item[0].title.rendered}</h2></li>`
$(".mypanel").html(text);
});
</script>
</div>
I read that probably $.map() would be a potential solution to my problem but can't figure out how to use it properly in this case.
Thank you for any help!
I guess if you get all the values in your response then simply just iterate through that:
const perPage = 10; // 10 posts
const url = 'https://www.example.com/wp-json/wp/v2/posts?per_page=' + perPage;
const handleResponse = items => {
let text = '';
items.forEach(item => {
text += `<li><h2>${item.title.rendered}</h2></li>`;
};
$(".mypanel").html(text);
};
$.getJSON(url, handeResponse);
Please find here for the REST API all the other arguments: Arguments
I hope this helps!
Use the pagination which comes as part of the WP api. Then iterate over that. Just add ?per_page=10 to your URL:
http://example.com/wp-json/wp/v2/posts?per_page=10
More here: https://developer.wordpress.org/rest-api/using-the-rest-api/pagination/
I have this database, which looks like this
so the first keys are user uid taken from auth, and then the username he/she provided and what did they score for each match are taken also..
I just wanted to get each user total points - for example Ray total points is 45 and Wood total points is 44 but after looking through for the docs all I was able to do was just for one user, I have to write each user name and the specific match for each line to get the value.. now think of how it will be if they are dozens of users? hmm a lot of lines..
here is the JSON
the javascript code
var query = firebase.database().ref();
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
var Data1 = childSnapshot.child("Ray/Match1/Points").val();
var Data2 = childSnapshot.child("Ray/Match2/Points").val();
console.log(Data1 + Data2);
});
})
which will let me display, Ray total points, but not for Wood obviously I have to repeat it and write it..
So how do i solve this?
I took a look at your problem and I think I have your solution, or at the very least a PATHWAY to your solution. Ok, first I'll explain the basic issue, then I'll attempt to provide you with some generic-ish code (I'll attempt to use some of the variables you used). And away we go!
Basically what I see is 2 steps...
STEP 1 - You need to use a "constructor function" that will create new user objects with their own name (and/or user ID) and their own set of properties.
With that line of thinking, you can have the constructor function include properties such as "user name", "match points 1", "match points 2" and then a function that console logs the summary of each name and their total points from match points 1 and 2.
STEP 2 - You need to put the constructor function inside of a loop that will go through the database looking for the specific properties you need to fill in the properties needed by the constructor function to spit out the info you're looking for.
So... and let's take a deep breath because that was a lot of words... let's try to code that. I'll use generic properties in a way that I think will make it easy for you to insert your own property/variable names.
var user = function(name, match1, match2){
this.name = name;
this.match1 = match1;
this.match2 = match2;
this.pointTotal = function(match1, match2) {
console.log(match1 + match2);};
this.summary = function(){
console.log(name + " has a total of " + pointTotal + "
points.");};
}
the "This" part of the code allows ANY user name to be used and not just specific ones.
Ok, so the code above takes care of the constructor function part of the issue. Now it doesn't matter how many users you need to create with unique names.
The next step is to create some kind of loop function that will go through the database and fill in the properties needed to create each user so that you can get the total points from EVERY user and not just one.
Again, I will use generic-ish property/variable names...
var key = childSnapshot.key;
while(i = 0; i < key.length + 1; i++) {
var user = function(name, match1, match2){
this.name = name;
this.match1 = match1;
this.match2 = match2;
this.pointTotal = function(match1, match2) {
console.log(match1 + match2);};
this.summary = function(){
console.log(name + " has a total of " + pointTotal + " points.");};
}
}
That is a whole lot of words and the code is a hybrid of generic property names/variables and of property names/variables used by you, but I'm certain that I am on the correct pathway.
I have a lot of confidence that if you used the code and EXPLANATION that I provided, that if you plug in your own variables you will get the solution that you need.
In closing I just want to say that I REALLY hope that helps and if it doesn't I'd like to help solve the problem one way or another because I need the practice. I work a job with weird hours and so if I don't answer right away I am likely at my job :(
Good luck and I hope I helped!
simply add total node to your db
|_Id
|_ $userId:
| |_ Ray
| | |_ Match1:24
| | |_ Match2:21
| |_ total:45
and then get user`s total
var query = firebase.database().ref();
query.once("value")
.then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var total = childSnapshot.child("total").val();
console.log(total);
});
})
you can add the total node using cloud functions
Check out this implementation. No need for cloud function.
firebase().database().ref().on('value', function(snapshot) {
snapshot.forEach((user)=>{
user.forEach((matches)=> {
var total = 0;
matches.forEach((match)=> {
total += match.val().Points;
});
console.log(total);
});
});
})
If the key is the user's Id, why add yet another nested object with the user's name? Do you expect one user to have multiple usernames? That sounds weird and adds on complexity, as you have probably noticed. If you need to keep the user name somewhere in Firebase, it is recommended that you dedicate a user details section somewhere directly under the user Id key. Here is a JavaScript representation of the Firebase object structure:
{
a1230scfkls1240: {
userinfo: {
username: 'Joe'
},
matches: {
asflk12405: {
points: 123
},
isdf534853: {
points: 345
}
}
}
}
Now, getting to the total points seems a bit more straightforward, does it not? 😎
To help you without modifying your current database structure, all you need is to loop through all the userId+username+matches permutation in your database. Here is an example code to achieve just that, you do not need any special Firebase feature, just good old JavaScript for-of loop:
const query = firebase.database().ref();
query.once('value')
.then(snapshot => {
const points = {}
const users = snapshot.val()
for (const userId of Object.keys(users)) {
const userprofile = users[userId]
for (const username of Object.keys(userprofile)) {
const user = userprofile[username]
for (const matchId of Object.keys(user)) {
const match = user[matchId]
// Store the points per user, per profile, or per both, depending on your needs
points[username] = points[username] === undefined
? points[username] = match.points
: points[username] += match.points
}
}
}
})
I'm trying to do something that is beyond my junior coding capabilities. I have created a function that will parse API data into Google Spreadsheet, but no matter what I've tried (and searched online for answers), the results are only being posted to a single column.
The code I am using currently is:
function getAPIdata (URL,key){
var apiurl = "https://example.com/Site/"+URL+"/students?&ID="+key
var rank_data = parse(apiurl)
var result = []
var data_dictionary = rank_data.Student
for (var i in data_dictionary){
result.push(data_dictionary[i].Name)
result.push(data_dictionary[i].Grade)
}
return result
}
The data in question that is being parsed is
Student": [
{
"Name": Adam,
"Grade": 75
},
{
"Name": Alan,
"Grade": 90
}
What is happening is that when I call the function in excel I am getting a single column with:
Adam
75
Alan
90
What I would like to do is have the following (spaces here delineate another column)
Adam 75
Alan 90
Basically, I have a 1x4 output and I would like a 2x2 output. Is there anyway I could do this? I realize I can call the function twice and push different data sets each time, but in this case I can only call the API once for all data. I thought about potentially pulling the data, caching it but before I delve down learning a path that will not bear fruit, I was hoping some of the experts here could weigh in.
Thanks for reading!
I think you can use [] and push a row at a time, like
function getAPIdata (URL,key){
var apiurl = "https://example.com/Site/"+URL+"/students?&ID="+key
var rank_data = parse(apiurl)
var result = []
var data_dictionary = rank_data.Student
for (var i in data_dictionary){
result.push([data_dictionary[i].Name, data_dictionary[i].Grade])
}
return result
}
I'm trying to get all organic entrances for a single URI. I filtered for ga:pagepath==uri and tried to use the segment ga:organicSearches. However the segment doesn't seem to work! I get the following error: "Invalid value 'ga:organicSearches' for segment parameter" Any ideas on how to fix this?
Here is my funtion:
function getEntrancesForUri(uri) {
var endDate = '2016-01-26';
var startDate = '2015-12-28';
var profileId = xxxxxxxx;
var tableId = 'ga:' + profileId;
var optArgs = {
'filters': 'ga:pagePath=='+uri,
'segment': 'ga:organicSearches'
};
var result = Analytics.Data.Ga.get(
tableId,
startDate,
endDate,
'ga:entrances',
optArgs
);
if (result) {
return result;
} else {
return 0;
}
}
That is not how you construct a segment. Also ga:organicSearches is a metric, and you probably want to segment by a dimension.
You can use a dynamic segment as described here which would probably look like this:
sessions::condition::ga:medium==organic
This segments out sessions that have arrived via an organic search.
Alternatively you can create your segment in the GA interface and find the segment id via the Query Explorer, and use that in your query. Testing your queries in the Query Explorer is a good idea in any case, since you get instant feedback and sometimes even a useful error message.