Youtube API Playlist - List playlist stopped working - javascript

I have a strange issue on a system that creates a youtube playlist, and then fills the playlist with videos from a database table.
The code is Version Controlled by GIT, and have no commits in the code for 3-4 months, and it has worked up to a couple of days back.
Suddenly it can't find the items, and therefore doesn't find the id, of the item that it should find. The system creates a list, then find the latest created playlist (which is the one you just created), and then fills the playlist up normally.
I'm not very good as javascript to be honest, are there any good javascript developers out there that can solve this? The error seems pretty common when googling, but In addition to the youtube api use, I find it hard to figure out the issue. Why it suddenly doesn't result items. (If I run a GET in Postman, ill get the correct playlist, so it should be something in the code that isn't working 100%)
function createPlaylist() {
var client = document.getElementsByName("client")[0].value;
var description = document.getElementsByName("information")[0].value;
return gapi.client.youtube.playlists.insert({
"part": [
"snippet,status"
],
"resource": {
"snippet": {
"title": client,
"description": description,
"position": 1,
"resourceId": {
"kind": "youtube#video",
"videoId": "mhmGwTDpPf0"
},
"tags": [
"postural workout"
],
"defaultLanguage": "en"
},
"status": {
"privacyStatus": "public"
}
}
})
.then(function(response) {
return gapi.client.youtube.playlists.list({
"part": [
"id,snippet,contentDetails"
],
"maxResults": 1,
"mine": true
})
.then(function(response) {
console.log("Response", response);
MyVars.latestPlaylistID = response.result.items[0].id;
pID = MyVars.latestPlaylistID
console.log(pID + " is the latest playlist");
var doms = document.getElementsByTagName("tr");
// Get every TR into an array
var array = $('tbody > tr').map(function() {
return $.map($(this).data(), function(v) {
return v;
});
}).get();
//array.reverse();
var array = array.filter(function(element){ return element.length>=11});
videosIdArray = array.reverse();
console.log(pID, videosIdArray, 0);
addVideoToPlayList(pID, videosIdArray, 0);
// setTimeout(addVideoToPlayList(pID, videosIdArray, 0), 5000);
document.getElementById("playlistID").innerHTML = 'https://www.youtube.com/playlist?list=' + pID;
document.getElementById("playlistID").href = 'https://www.youtube.com/playlist?list=' + pID;
},
function(err) { console.error("ListPlaylist error", err); });
},
function(err) { console.error("InsertPlaylist error", err); });
}
This is what happens now:
Error
And as you can see the items array is empty.

I have now solved it!
By breaking down the function into smaller functions it seems to give me the correct result. Why the problem suddenly occured is still uknown, but I'm glad it now works.
This is the final solution if others out there are trying to solve similiar issue.
function createPlaylist() {
var client = document.getElementsByName("client")[0].value;
var description = document.getElementsByName("information")[0].value;
return gapi.client.youtube.playlists.insert({
"part": [
"snippet,status"
],
"resource": {
"snippet": {
"title": client,
"description": description,
"position": 1
},
"status": {
"privacyStatus": "public"
}
}
}).then(function(response) {
console.log("Response", response);
});
}
function addToPlaylist() {
return gapi.client.youtube.playlists.list({
"part": [
"id,snippet,contentDetails"
],
"maxResults": 1,
"mine": true
})
.then(function(response) {
console.log("Response", response);
MyVars.latestPlaylistID = response.result.items[0].id;
pID = MyVars.latestPlaylistID
console.log(pID + " is the latest playlist");
var doms = document.getElementsByTagName("tr");
var array = $('tbody > tr').map(function() {
return $.map($(this).data(), function(v) {
return v;
});
}).get();
var array = array.filter(function(element){ return element.length>=11});
videosIdArray = array.reverse();
console.log(pID, videosIdArray, 0);
addVideoToPlayList(pID, videosIdArray, 0);
},
function(err) { console.error("ListPlaylist error", err); });
}

Related

How to access a specific element in JSON in Google Apps Script?

I need to access the nav for a specific date from the below JSON. eg : data[date="20-04-2022"].nav
How do I do it in Google Apps Script?
The standard JSON notation is not working.
{
"meta":{
"fund_house":"Mutual Fund",
"scheme_type":"Open Ended Schemes",
},
"data":[
{
"date":"22-04-2022",
"nav":"21.64000"
},
{
"date":"21-04-2022",
"nav":"21.69000"
},
{
"date":"20-04-2022",
"nav":"21.53000"
}
],
"status":"SUCCESS"
}
In your situation, I thought that it is required to retrieve the element including "date": "20-04-2022" from the array of data. So, how about the following sample script?
Sample script:
const obj = {
"meta": {
"fund_house": "Mutual Fund",
"scheme_type": "Open Ended Schemes",
},
"data": [
{
"date": "22-04-2022",
"nav": "21.64000"
},
{
"date": "21-04-2022",
"nav": "21.69000"
},
{
"date": "20-04-2022",
"nav": "21.53000"
}
],
"status": "SUCCESS"
};
const search = "20-04-2022";
const res = obj.data.find(({ date }) => date == search);
const value = res && res.nav;
console.log(value) // 21.53000
For example, if the search value is always found, you can use the following script.
const res2 = obj.data.find(({ date }) => date == search).nav;
Reference:
find()
Added 1:
From your following reply,
This looks like standard java script. Does not work in google apps script(script.google.com/home). Getting syntax error for this line : const res = obj.data.find(({ date }) => date == search);
I'm worried that you are not enabling V8 runtime. Ref If you cannot use V8 runtime, how about the following sample script?
Sample script:
var obj = {
"meta": {
"fund_house": "Mutual Fund",
"scheme_type": "Open Ended Schemes",
},
"data": [
{
"date": "22-04-2022",
"nav": "21.64000"
},
{
"date": "21-04-2022",
"nav": "21.69000"
},
{
"date": "20-04-2022",
"nav": "21.53000"
}
],
"status": "SUCCESS"
};
var search = "20-04-2022";
var res = obj.data.filter(function (e) { return e.date == search })[0];
var value = res && res.nav;
console.log(value) // 21.53000
Added 2:
From your following reply,
This looks like standard java script. Does not work in google apps script(script.google.com/home). Getting syntax error for this line : const res = obj.data.find(({ date }) => date == search);
I am trying to write a google apps script to fetch data from a url. But google seems to have its own way of handling the JSON data which I am unable to figure out. developers.google.com/apps-script/guides/services/…
I understood that your actual goal was to retrieve the value using Web Apps. If my understanding of your actual goal, how about the following sample script?
1. Sample script:
Please copy and paste the following script to the script editor and save the script.
function doGet(e) {
var search = e.parameter.search;
var obj = {
"meta": {
"fund_house": "Mutual Fund",
"scheme_type": "Open Ended Schemes",
},
"data": [
{
"date": "22-04-2022",
"nav": "21.64000"
},
{
"date": "21-04-2022",
"nav": "21.69000"
},
{
"date": "20-04-2022",
"nav": "21.53000"
}
],
"status": "SUCCESS"
};
var res = obj.data.filter(function (e) { return e.date == search })[0];
var value = res && res.nav;
return ContentService.createTextOutput(value);
}
I think that this sample script can be used with and without V8 runtime.
2. Deploy Web Apps.
In this case, please check the official document. Please set it as follows.
Execute as: Me
Anyone with Google account: Anyone
In this case, it supposes that you are using new IDE. Please be careful this.
3. Testing.
Please access to the URL like https://script.google.com/macros/s/{deploymentId}/exec?search=20-04-2022 using your browser. By this, the result value is returned.
`

How to add data fetched from a API to an HTML DataTable?

I'm trying to complete a DataTable with information gathered from an API.
I made a "fiddle" here to make it easier to help and understand what I mean:
http://live.datatables.net/jujofoye/3/edit
I'm starting from an HTML table containing only ID's. Then I use that ID in a rowCallback to call an API and write the fetched value in the table with jQuery $('td:eq(1)', nRow).html( json.Title );
function customFnRowCallback( nRow, aData, iDisplayIndex ) {
var imdbID = aData[0];
fetch("http://www.omdbapi.com/?i="+imdbID+"&plot=short&r=json&tomatoes=true")
.then(function(response) {
return response.json();
})
.then(function(json) {
$('td:eq(1)', nRow).html( json.Title );
})
.catch(function(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
});
}
However the problem here is that you cannot sort on the second column. Even though you can see the data perfectly fine. I bet the DataTable doesn't really know there is new data and you end up sorting empty values instead of the values you added.
A second effect of this same issue (which does not show in my fiddle) is that collapsed rows (rows should collapse when not enough width) also show up empty when the row is expanded.
A third effect is that the search doesn't work on fetched data.
Is there a way to really add the fetched data to the DataTable? Not cosmetically that is.
(Note: All the responses I can find are about populating a full DataTable with an AJAX request. I'm only adding data to an already populated DataTable)
I took a different approach. I used the DataTable ajax with when/done so it will not refresh the table until all the gets are processed.
I set sorting so the list will come out alphabetically even those that is not the order of the list.
I also got unique set of values from imdb.
http://jsbin.com/yojoka/edit?html,js,output
<script type="text/javascript">
// Sample return set from
var sampleReturn = { "Title": "Seven Samurai", "Year": "1954", "Rated": "UNRATED", "Released": "19 Nov 1956", "Runtime": "207 min", "Genre": "Adventure, Drama", "Director": "Akira Kurosawa", "Writer": "Akira Kurosawa (screenplay), Shinobu Hashimoto (screenplay), Hideo Oguni (screenplay)", "Actors": "ToshirĂ´ Mifune, Takashi Shimura, Keiko Tsushima, Yukiko Shimazaki", "Plot": "A poor village under attack by bandits recruits seven unemployed samurai to help them defend themselves.", "Language": "Japanese", "Country": "Japan", "Awards": "Nominated for 2 Oscars. Another 5 wins & 6 nominations.", "Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTc5MDY1MjU5MF5BMl5BanBnXkFtZTgwNDM2OTE4MzE#._V1_SX300.jpg", "Metascore": "98", "imdbRating": "8.7", "imdbVotes": "238,165", "imdbID": "tt0047478", "Type": "movie", "Response": "True" };
var deferreds = [];
var newData = [];
$(function ($) {
var dt = $("#example").DataTable({
columnDefs:[{targets:[0, -1], width:"150px"}],
columns: [
{ data: "imdbID" },
{ data: "Title" },
{ "data": "Year" }
],
deferLoading: 0,
deferRendering: true,
"order": [[ 1, "asc" ]],
ajax: function (data, cb, setting) {
// get the list of ids created by DataTables from the embedded html
var curData = $("#example").DataTable().rows().data();
// if you don't clear, you will end up with double entries
$("#example").DataTable().clear();
$.each(curData, function (i, item) {
var sr = { i: item.imdbID, plot:"short", r:"json", "tomatoes":true};
deferreds.push(
$.get("http://www.omdbapi.com/", sr)
.then(function (response) {
// push the response into the global array
newData[newData.length] = response;
})
);
});
// now make all of the calls. When done, use the callback to return the data and populate the table
$.when.apply(null, deferreds)
.done(function () {
cb({ data: newData })
});
}
});
});
</script>
You're correct in that DataTable doesn't know what's in the table to sort.
I would say to run the function once the table is completely made.
$('#example').find('tbody tr').each(customFnRowCallback);
function customFnRowCallback()
{
var $this = $(this);
var imdbID = $this.find('td:eq(0)').text();
fetch("http://www.omdbapi.com/?i="+imdbID+"&plot=short&r=json&tomatoes=true")
.then(function(response) {
return response.json();
})
.then(function(json) {
$this.find('td:eq(1)').text( json.Title );
})
.then(function() {
$('#example').DataTable();
})
.catch(function(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
});
}

Fetching relation to PFObject cloud code

I have a PFUser that has a days relation to a Day PFObject.
In my database it looks like this:
{
"_id": "WjLAnMuRmp",
"name": "c",
"_created_at": {
"$date": "2016-08-04T15:28:51.759Z"
},
"_updated_at": {
"$date": "2016-08-24T19:44:44.774Z"
},
"days": [
{
"__type": "Pointer",
"className": "Day",
"objectId": "BrQwmKAbJC"
},
{
"__type": "Pointer",
"className": "Day",
"objectId": "6wuDMl4kKI"
}
]
}
Pretty straight forward. In my cloud code, I'm trying to send up a PFUser objectId, then fetch all the days they have and iterate over them. For some strange reason I keep getting 0 returned when I do a relation query.
Here is what I'm working with:
Parse.Cloud.define("getDayAveragesForUser", function(request, response) {
console.log("-getDayAveragesForUser");
// Create the query on the User class
var fetchedUser = new Parse.User({id:request.params.userObjectId});
console.log("the fetched user: " + fetchedUser.id);
var relation = fetchedUser.relation("days");
var query = relation.query();
query.limit(365);
query.ascending("createdAt");
query.find({
success: function(results) {
console.log("Successfully retrieved " + results.length + " Days.");
},
error: function(error) {
console.log("Error: " + error.code + " " + error.message);
}
});
});
When I print the fetchedUser.id it's correct so I know I'm on the right user. This seems based on the documentation example:
var relation = user.relation("likes");
relation.query().find({
success: function(list) {
// list contains the posts that the current user likes.
}
});
This should be working fine.
===
I just add this to my Cloud Code to test:
var days = fetchedUser.get("days");
console.log("type of: " + typeof days);
which from this I get:
type of: undefined
The reason is that your days are not saved as relations but as a pointers. And in parse relations and pointers are handled in different ways.
In order to fetch the days pointer you need to change your query to look like the following:
var userQuery = new Parse.Query(Parse.User);
userQuery.include("days"); // include the days pointer in the results
userQuery.get(request.params.userObjectId, {
success: function(user) {
// This function will *not* be called.
console.log(user.get("days")); // print the days to console
},
error: function(error) {
}
});

Cloud Code object.save() results in 'object not found' with very strange PUT command

Issue Description
I have a simple Cloud Code command to create or update an object. If there is NO objectId passed in, the routine creates a new object and returns the objectId. If the objectId exists in the parameter list, it fetches the object and updates the parameters accordingly.
The routine works for new objects fine.
The object.save() is failing when I try to update an object, despite the object.fetch() sub-routine working.
error: code=101, message=Object not found.
Verbose server logs indicate a very strange PUT command...
PUT /parse/classes/Receipt/[object%20Object]
what I would expect to see is
PUT /parse/classes/Receipt/GJaXcf7fLD
Object ACL is public r+w
Why is the object.save() not working with a valid objectId?
_
Cloud Code
Parse.Cloud.define("uploadReceipt", function(request,response) {
var Receipt = Parse.Object.extend("Receipt");
var receipt = new Receipt();
// passed in parameters are ['property' : ['type' : t, 'value' : v]]
var dict = request.params;
var objectIdDict = dict["objectId"];
console.log("Object Dict: " + objectIdDict);
Parse.Promise.as().then(function() {
// if we already have an objectId we are UPDATING
// Need to FETCH first
if (objectIdDict != undefined) {
console.log("Searching for ID: " + objectIdDict["value"]);
receipt.set("objectId",objectIdDict["value"]);
return receipt.fetch();
}
else {
console.log("NEW RECEIPT");
return Parse.Promise.as(receipt);
}
}).then(function(receipt) {
console.log("Receipt: " + receipt.id);
// copy over the keys from our passed in parameters to the object
for (var key in dict) {
//console.log("Key: " + key + " Value: " + dict[key]["value"]);
if (dict[key]["type"] == "Raw") {
console.log("Key: " + key + " Value: " + dict[key]["value"]);
receipt.set(key,dict[key]["value"]);
}
else if (dict[key]["type"] == "Date" && key != "updatedAt") {
console.log("Key: " + key + " Value: " + dict[key]["value"]);
var time = dict[key]["value"] * 1000; // milliseconds
receipt.set(key,new Date(time));
}
else {
// object type
var Obj = Parse.Object.extend(dict[key]["type"]);
var newObj = new Obj();
newObj.id = dict[key]["value"];
receipt.set(key,newObj);
}
}
// make sure our user is set
receipt.set("user",request.user);
// adjust the status because it has now been uploaded
receipt.set("status",RECEIPT_SUBMITTED);
console.log("Prior to save");
return receipt.save();
}).then(function(receipt) {
console.log("Finished");
response.success({"status":receipt.get("status"),"objectId":receipt.id});
},function (error) {
console.log(error);
response.error(error);
});
});
Steps to reproduce
Call the cloud code from iOS SDK with data for a new object
Notice that the command works and a new object is added to the database
Call the command again with updated information
Notice that the command fails with object not found
Expected Results
Object should be updated accordingly
Actual Outcome
error: code=101, message=Object not found.
Environment Setup
Server
parse-server version: 2.2.12
Operating System: Mac OS X 10.11.5
Hardware: MacBook Pro 2010
Localhost or remote server? Localhost
Javascript: Parse/js1.8.5
NodeJS 5.10.1
Database
MongoDB version: 3.2.4
Hardware: MacBook Pro 2010
Localhost or remote server? Localhost
Logs/Trace
Storing NEW object returns
verbose: POST /parse/classes/Receipt { 'user-agent': 'node-XMLHttpRequest, Parse/js1.8.5 (NodeJS 5.10.1)',
accept: '*/*',
'content-type': 'text/plain',
host: 'localhost:1337',
'content-length': '471',
connection: 'close' } {
"date": {
"__type": "Date",
"iso": "2016-06-19T00:30:37.492Z"
},
"category": {
"__type": "Pointer",
"className": "Category",
"objectId": "XZ1bSHtZBY"
},
"status": 0,
"amount": 61.45,
"notes": "Hopefully this works well",
"gui_status": -1,
"currency": "USD",
"user": {
"__type": "Pointer",
"className": "_User",
"objectId": "vL4ih9BAX8"
}
}
verbose: {
"status": 201,
"response": {
"objectId": "GJaXcf7fLD",
"createdAt": "2016-06-19T00:30:57.092Z"
},
"location": "http://localhost:1337/parse/classes/Receipt/GJaXcf7fLD"
}
Finished
verbose: {
"response": {
"result": {
"status": 0,
"objectId": "GJaXcf7fLD"
}
}
}
Attempt to Update object returns
verbose: PUT /parse/classes/Receipt/[object%20Object] { 'user-agent': 'node-XMLHttpRequest, Parse/js1.8.5 (NodeJS 5.10.1)',
accept: '*/*',
'content-type': 'text/plain',
host: 'localhost:1337',
'content-length': '473',
connection: 'close' } {
"category": {
"__type": "Pointer",
"className": "Category",
"objectId": "XZ1bSHtZBY"
},
"status": 0,
"amount": 5.47,
"notes": "How about now",
"gui_status": 0,
"date": {
"__type": "Date",
"iso": "2016-06-19T00:12:25.788Z"
},
"currency": "USD",
"user": {
"__type": "Pointer",
"className": "_User",
"objectId": "vL4ih9BAX8"
}
}
verbose: error: code=101, message=Object not found.
ParseError { code: 101, message: 'Object not found.' }
verbose: error: code=141, code=101, message=Object not found.
Figured it out thanks to some help from the parse-server community and GitHub user flovilmart
In the case of 'updating' an object, I was including a dictionary entry for the Receipt. This was successfully retrieving the Receipt that I wanted to update.
However, the issue was that once I pulled in the receipt object and was iterating through my dictionary of properties to update... I ran into the Receipt object information again. Thus I was trying to add a property of Receipt pointer to my Receipt with the pointer being itself! Ugh.
The very last else clause needed a condition on it to NOT include the pointer to the Receipt (itself)
for (var key in dict) {
if
....
else if (dict[key]["type"] != "Receipt"){
// object type, but don't include ourself! (the Receipt)
var Obj = Parse.Object.extend(dict[key]["type"]);
var newObj = new Obj();
newObj.set("objectId",dict[key]["value"]);
receipt.set(key,newObj);
}
}

Unable to delete a youtube playlist using youtube api v3

I am trying to delete a playlist that I have created but keep receiving a 404 error.
I have a global var playlistId to remember the playlistId that I have created.
var playlistId
I create the playlist like so :
function createPlaylist() {
var request = gapi.client.youtube.playlists.insert({
part: 'snippet,status',
resource: {
snippet: {
title: 'hard coded title',
description: 'Hard Coded Description'
},
status: {
privacyStatus: 'private'
}
}
});
request.execute(function(response) {
var result = response.result;
if (result) {
playlistId = result.id;
console.log("created playlist " + playlistId)
}
});
}
Then I delete a playlist like so :
function deletePlaylist() {
var request = gapi.client.youtube.playlistItems.delete({
id: playlistId
}).execute();
}
404 Error that I receive is :
{
"error": {
"errors": [
{
"domain": "youtube.playlistItem",
"reason": "playlistItemNotFound",
"message": "Playlist item not found.",
"locationType": "parameter",
"location": "id"
}
],
"code": 404,
"message": "Playlist item not found."
}
}
I am giving the playlistId of the PlayList that I have created yet the playlist can not be deleted.
Can anyone give some guidance?
deletePlaylist appears to be attempting to delete a PlaylistItem (i.e. a video) rather than a Playlist itself. Could you try replacing playlistItems with playlists?

Categories

Resources