This code worked until I put it in a ForEach loop. The issue appears to be with the 'await fetch(integromat_webhook_url + aj);' line as it throws this error 'await is only valid in async function'.
I'm trying to send multiple webhooks to integromat.
Is there a way to do without the AWAIT part or make it an ASYNC Function please?
I'm a noob and just learning javascript :-).
Thanks
Jonathan
console.log('Filtered PIDs:', filteredPids);
let worksheetsCreated = filteredPids.length;
let integromat_webhook_url = "";
if(worksheetsCreated > 0){
output.markdown(worksheetsCreated + " worksheets created and being sent to indiviudal groups.");
//ADD FILTERED PRODUCTION WORKSHEETS TO TABLE
let recordsCreated = await batchAnd('Create', groupworksheetsBase, filteredPids);
//GET ARRAY OF GROUPS IN FILTERED PRODUCTION WORKSHEET
let unique = [...new Set(filteredPids.map(item => item.fields.Group))];
console.log('unique groups in filtered PIDs',unique);
//LOOP THROUGH UNIQUE GROUPS
unique.forEach(function(uGroup) {
integromatArray = filteredPids.filter(pid => pid.fields.Group == uGroup)
console.log(uGroup, integromatArray);
switch(uGroup) {
case 'Birkenhead':
integromat_webhook_url = "https://hook.integromat.com/mksobdvdxxxxxxxxxxx?pidsArray=";
break;
case 'Taupo':
integromat_webhook_url = "https://hook.integromat.com/9c6y4279kxxxxxxxxxx?pidsArray=";
break;
}
const aj = JSON.stringify(integromatArray);
console.log('stringify array',aj);
await fetch(integromat_webhook_url + aj);
});
} else {
output.markdown("No new worksheets to add.");
}
Thanks so much
Jonathan
just add async before the function keyword
unique.forEach(async function(uGroup) {
integromatArray = filteredPids.filter(pid => pid.fields.Group == uGroup)
console.log(uGroup, integromatArray);
switch(uGroup) {
case 'Birkenhead':
integromat_webhook_url = "https://hook.integromat.com/mksobdvdxxxxxxxxxxx?pidsArray=";
break;
case 'Taupo':
integromat_webhook_url = "https://hook.integromat.com/9c6y4279kxxxxxxxxxx?pidsArray=";
break;
}
const aj = JSON.stringify(integromatArray);
console.log('stringify array',aj);
await fetch(integromat_webhook_url + aj);
});
I used this approach to get it working as suggested by a friend of mine...
console.log('Filtered PIDs:', filteredPids);
let worksheetsCreated = filteredPids.length;
let integromat_webhook_url = "";
if(worksheetsCreated > 0){
output.markdown(worksheetsCreated + " worksheets created and being sent to indiviudal groups.");
//ADD FILTERED PRODUCTION WORKSHEETS TO TABLE
let recordsCreated = await batchAnd('Create', groupworksheetsBase, filteredPids);
//GET ARRAY OF GROUPS IN FILTERED PRODUCTION WORKSHEET
const unique = [...new Set(filteredPids.map(item => item.fields.Group))];
console.log('unique groups in filtered PIDs', unique);
//LOOP THROUGH UNIQUE GROUPS
await Promise.all(
unique.map(async uGroup => {
integromatArray = recordsArray.filter(pid => pid.fields.Group == uGroup);
console.log(uGroup, integromatArray);
switch (uGroup) {
case 'Birkenhead':
integromat_webhook_url = 'https://hook.integromat.com/mksobdvdu8uydiq9x22mxptgaye6ueji?pidsArray=';
break;
case 'Taupo':
integromat_webhook_url = 'https://hook.integromat.com/9c6y4279kydmqm7hswjutwhp7fu814aa?pidsArray=';
break;
}
const aj = JSON.stringify(integromatArray);
console.log('stringify array', aj);
console.log('url',integromat_webhook_url + aj);
const result = await fetch(integromat_webhook_url + aj);
return result;
})
);
} else {
output.markdown("No new worksheets to add.");
}
Change your forEach loop to a for loop and do not forget to put the async keyword before the function keyword like :
async function test() {
}
Related
In total I have two files first one is tester and second is the solution for tester file
Here is my Tester File
const data = require('./data');
const result0 = data.results[0];
const { getTaxonPhotos } = require('./observations');
const isINaturalistPath = (pathname) =>
/(square.jpe?g|original.jpe?g|small.jpe?g|medium.jpe?g|large.jpe?g|_s.jpe?g)$/.test(pathname);
const hasIdQueryParam = (search) => /^\?\d+$/.test(search);
const isUrl = (url) => {
const { pathname, search } = new URL(url);
if (!isINaturalistPath(pathname)) {
throw new Error(`URL path doesn't look like an iNaturalist photo: ${pathname}`);
}
if (!hasIdQueryParam(search)) {
throw new Error(`URL origin doesn't have expected id on query string: ${search}`);
}
return true;
};
describe('Problem 06 - getTaxonPhotos() function', function () {
let sample, samples, sampleData;
beforeEach(() => {
sample = Object.assign({}, result0);
samples = [sample];
sampleData = { results: samples };
});
test('should return an Array of Objects with the right URLs', function () {
let result = getTaxonPhotos(sampleData);
expect(Array.isArray(result)).toBe(true);
expect(result.length).toBe(1);
const photos = result[0];
expect(isUrl(photos.square)).toBe(true);
expect(isUrl(photos.original)).toBe(true);
expect(isUrl(photos.small)).toBe(true);
expect(isUrl(photos.medium)).toBe(true);
expect(isUrl(photos.large)).toBe(true);
});
test('should return an empty Array if missing taxon', function () {
delete sample.taxon;
let result = getTaxonPhotos(sampleData);
expect(Array.isArray(result)).toBe(true);
expect(result.length).toBe(0);
});
test('real-data should produce the expected result', function () {
let result = getTaxonPhotos(data);
expect(Array.isArray(result)).toBe(true);
expect(result.length).toBe(9);
result.forEach((photos) => {
expect(isUrl(photos.square)).toBe(true);
expect(isUrl(photos.original)).toBe(true);
expect(isUrl(photos.small)).toBe(true);
expect(isUrl(photos.medium)).toBe(true);
expect(isUrl(photos.large)).toBe(true);
});
});
test('URLs should end with the observation ID on the query string', () => {
let taxonPhotos0 = getTaxonPhotos(data)[0];
let observationId = result0.id;
expect(taxonPhotos0.square.endsWith(`?${observationId}`)).toBe(true);
expect(taxonPhotos0.original.endsWith(`?${observationId}`)).toBe(true);
expect(taxonPhotos0.small.endsWith(`?${observationId}`)).toBe(true);
expect(taxonPhotos0.medium.endsWith(`?${observationId}`)).toBe(true);
expect(taxonPhotos0.large.endsWith(`?${observationId}`)).toBe(true);
});
});
Here is my solution for the tester file or you can say function to solve the tester code
function getTaxonPhotos(data) {
// TODO
let patt = /(http(s)?:\/\/)/
let arr = Array();
let pho_obj = {
original: "",
square: "",
small: "",
medium: "",
large: ""
};
data.results.forEach(function(element) {
if (element.hasOwnProperty('taxon') && element.taxon.default_photo) {
// Separate values and find url and id in them
let _values = Object.values(element.taxon.default_photo);
let _url = _values.find(sector => sector.match(patt));
let _id = _values.find( element => typeof element === 'number').toString();
let observationId = "1384377507";
// split the url before file extension
_url = _url.substring(0, (_url.indexOf(_id) + _id.length + 1));
// using a for loop with swith to make correct url
for (let i in pho_obj) {
switch (`${i}`) {
case "original":
pho_obj.original = _url + "original.jpg"+`?${observationId}`;
break;
case "square":
pho_obj.square = _url + "square.jpg"+`?${observationId}`;
break;
case "small":
pho_obj.small = _url + "small.jpg"+`?${observationId}`;
break;
case "medium":
pho_obj.medium = _url + "medium.jpg"+`?${observationId}`;
break;
case "large":
pho_obj.large = _url + "large.jpg"+`?${observationId}`;
break;
}
}
arr.push(pho_obj);
}
});
return arr;
}
I successfully completed 3 conditions but 1 last goes wrong can you help me solve this (I test using jest in javascript)
√ should return an Array of Objects with the right URLs (3 ms)
√ should return an empty Array if missing taxon
√ real-data should produce the expected result (5 ms)
× URLs should end with the observation ID on the query string (3 ms)
let taxonPhotos0 = getTaxonPhotos(data)[0];
I don't think you have anything define for data
did you try
let taxonPhotos0 = getTaxonPhotos(sampleData)[0];
Flow:
The user submits a queryValue in index.html.
Three API calls are made (using a function called ytAxiosGetFunc) based on the queryValue.
The returned values are put in three arrays: ytQueryAppJs, ytCoverAppJs and ytLiveAppJs.
ytCoverAppJs and ytLiveAppJs contains redundant values. These are removed using a function called compareAndRemove.
Two new arrays are allocated which contain unique values from for each of these respectively. These are ytCoverUniqueAppJs and ytLiveUniqueAppJs.
Hence, a total of five arrays get logged in console, based on the query.
Expected Console Log:
All the arrays are filled.
Current Console Log:
All the arrays are filled, except ytCoverUniqueAppJs and ytLiveUniqueAppJs. These are empty.
Source Code from 'app.js':
// https://stackoverflow.com/a/14930567/14597561
function compareAndRemove(removeFromThis, compareToThis) {
return (removeFromThis = removeFromThis.filter(val => !compareToThis.includes(val)));
}
// Declaring variables for the function 'ytAxiosGetFunc'
let apiKey = "";
let urlOfYtAxiosGetFunc = "";
let ytResponse = "";
let ytExtractedResult = [];
// This function GETs data, parses it, allocates required values in an array.
async function ytAxiosGetFunc(queryOfYtAxiosGetFunc, maxResultsOfYtAxiosGetFunc) {
apiKey = "AI...5U"
urlOfYtAxiosGetFunc = "https://www.googleapis.com/youtube/v3/search?key=" + apiKey + "&part=snippet&order=relevance&type=video";
try {
ytResponse = await axios({
url: urlOfYtAxiosGetFunc,
method: "get",
params: {
q: queryOfYtAxiosGetFunc,
maxResults: maxResultsOfYtAxiosGetFunc
}
})
let ytResult = ytResponse.data;
for (i = 0; i < (ytResult.items).length; i++) {
ytExtractedResult[i] = ytResult.items[i].id.videoId;
// console.log(ytExtractedResult);
}
return (ytExtractedResult);
ytExtractedResult.length = 0;
ytResponse.length = 0;
} catch (e) {
console.log(e);
}
}
app.post("/", async function(req, res) {
// Accessing the queryValue user submitted in index.html.
query = req.body.queryValue;
// Fetcing top results related to user's query and putting them in the array.
ytQueryAppJs = await ytAxiosGetFunc(query, 4);
console.log("ytQueryAppJs");
console.log(ytQueryAppJs);
// Fetching 'cover' songs related to user's query and putting them in the array.
if (query.includes("cover") == true) {
ytCoverAppJs = await ytAxiosGetFunc(query, 8);
console.log("ytCoverAppJs");
console.log(ytCoverAppJs);
// Removing redundant values.
ytCoverUniqueAppJs = compareAndRemove(ytCoverAppJs, ytQueryAppJs);
console.log("ytCoverUniqueAppJs:");
console.log(ytCoverUniqueAppJs);
} else if (query.includes("live") == true) {
ytCoverAppJs = await ytAxiosGetFunc(query.replace("live", " cover "), 8);
console.log("ytCoverAppJs");
console.log(ytCoverAppJs);
// Removing redundant values.
ytCoverUniqueAppJs = compareAndRemove(ytCoverAppJs, ytQueryAppJs);
console.log("ytCoverUniqueAppJs:");
console.log(ytCoverUniqueAppJs);
} else {
ytCoverAppJs = await ytAxiosGetFunc(query + " cover ", 8);
console.log("ytCoverAppJs");
console.log(ytCoverAppJs);
// Removing redundant values.
ytCoverUniqueAppJs = compareAndRemove(ytCoverAppJs, ytQueryAppJs);
console.log("ytCoverUniqueAppJs:");
console.log(ytCoverUniqueAppJs);
}
// Fetching 'live performances' related to user's query and putting them in the array.
if (query.includes("live") == true) {
ytLiveAppJs = await ytAxiosGetFunc(query, 8);
console.log("ytLiveAppJs");
console.log(ytLiveAppJs);
// Removing redundant values.
ytLiveUniqueAppJs = compareAndRemove(ytLiveAppJs, ytQueryAppJs.concat(ytCoverUniqueAppJs));
console.log("ytLiveUniqueAppJs:");
console.log(ytLiveUniqueAppJs);
} else if (query.includes("cover") == true) {
ytLiveAppJs = await ytAxiosGetFunc(query.replace("cover", " live "), 8);
console.log("ytLiveAppJs");
console.log(ytLiveAppJs);
// Removing redundant values.
ytLiveUniqueAppJs = compareAndRemove(ytLiveAppJs, ytQueryAppJs.concat(ytCoverUniqueAppJs));
console.log("ytLiveUniqueAppJs:");
console.log(ytLiveUniqueAppJs);
} else {
ytLiveAppJs = await ytAxiosGetFunc(query + " live ", 8);
console.log("ytLiveAppJs");
console.log(ytLiveAppJs);
// Removing redundant values.
ytLiveUniqueAppJs = compareAndRemove(ytLiveAppJs, ytQueryAppJs.concat(ytCoverUniqueAppJs));
console.log("ytLiveUniqueAppJs:");
console.log(ytLiveUniqueAppJs);
}
// Emptying all the arrays.
ytQueryAppJs.length = 0;
ytCoverAppJs.length = 0;
ytCoverUniqueAppJs.length = 0;
ytLiveAppJs.length = 0;
ytLiveUniqueAppJs.length = 0;
});
(I am a beginner. Please guide and suggest a title to categorize this question for coming viewers.)
My friend suggested me to localise ytResponse and ytExtractedResult. So I declared them inside ytAxiosGetFunc.
Notice the commented code. Here's the required change:
// Declaring variables for the function 'ytAxiosGetFunc'
let apiKey = "";
let urlOfYtAxiosGetFunc = "";
// let ytResponse = "";
// let ytExtractedResult = [];
// This function GETs data, parses it, allocates required values in an array.
async function ytAxiosGetFunc(queryOfYtAxiosGetFunc, maxResultsOfYtAxiosGetFunc) {
let ytExtractedResult = [];
apiKey = "A...U"
urlOfYtAxiosGetFunc = "https://www.googleapis.com/youtube/v3/search?key=" + apiKey + "&part=snippet&order=relevance&type=video";
try {
let ytResponse = await axios({
url: urlOfYtAxiosGetFunc,
method: "get",
params: {
q: queryOfYtAxiosGetFunc,
maxResults: maxResultsOfYtAxiosGetFunc
}
})
let ytResult = ytResponse.data;
for (i = 0; i < (ytResult.items).length; i++) {
ytExtractedResult[i] = ytResult.items[i].id.videoId;
// console.log(ytExtractedResult);
}
return (ytExtractedResult);
// ytExtractedResult.length = 0; // These are unnecessary now.
// ytResponse.length = 0;
} catch (e) {
console.log(e);
}
}
Here's what I think was happening earlier:
ytQueryAppJs was getting 're-filled' for every ytAxiosGetFunc call. This was making ytQueryAppJs to have exact same values (on the same index) as the variable for which the call is actually made. For example, if the function call is made to assign values in ytCoverAppJs, it would set the same values for ytQueryAppJs as well. The same would happen at the time of calling function for ytLiveAppJs. This ultimately caused compareAndRemove function to clear out all the values.
Here's what I think is happening now:
The variables ytExtractedResult and ytResponse are being re-initialised for every call to the function ytAxiosGetFunc. This imply that they don't have the previous values. (And do not need to have their length set to zero.)
Thank you everyone for responding. :)
I tried to make and embed and add reactions to it.
but the embeds find is returning undefined when console.log
I am trying to make reaction role the following code is to create one.
I can successfully create embed but I can't add desired reactions because it is not able to find embed
const Discord = require('discord.js')
module.exports.run = async (client,message,args,con)=>{
message.channel.send("How many reaction role you want to create");
answer = await message.channel.awaitMessages(answer => answer.author.id != client.user.id,{max: 1});
const n = (answer.map(answers => answers.content).join())
if(isNaN(n)) return message.channel.send("Enter a Number")
message.channel.send("Enter the title");
answer = await message.channel.awaitMessages(answer => answer.author.id != client.user.id,{max: 1});
const embtitle = (answer.map(answers => answers.content).join())
var a = []
var b = []
for(var i =0; i<n;i++){
message.channel.send("Enter the emoji")
answer = await message.channel.awaitMessages(answer => answer.author.id != client.user.id,{max: 1});
a[i] = (answer.map(answers => answers.content).join())
message.channel.send("Enter the role name")
answer = await message.channel.awaitMessages(answer => answer.author.id != client.user.id,{max: 1});
b[i] = (answer.map(answers => answers.content).join())
}
function embstr(){
var finalString = '';
for(var i =0;i<n;i++){
finalString += a[i]+ ' '+b[i] +'\n';
}
return finalString;
}
const embed = new Discord.MessageEmbed()
.setTitle(embtitle)
.setColor("BLUE")
.setDescription(embstr());
message.channel.send(embed);
const embedMsg = message.embeds.find(msg => msg.title === 'some');
console.log(embedMsg)
for(var i = 0;i<n;i++){
var emoid = a[i].slice(1,-1)
emoid = emoid.split(':')
emoid = emoid[2];
console.log(emoid);
const embedMsg = message.embeds.find(msg => msg.title === embtitle);
console.log(embedMsg)
if(embedMsg){
message.react(emoid)
}
}
}
module.exports.config = {
command: 'create'
}
Instead of constantly trying to find the message you sent like this :
const embedMsg = message.embeds.find(msg => msg.title === 'some');
You could simply assign the message you sent to a variable, like this :
const embedMsg = await message.channel.send(embed); // I used await since I saw your function is asynchronous
Then react to the message this way :
await embedMsg.react('emote Name/ID/Whatever');
Hope this will help :)
Mediocre javascript developer here and need some help..
I want to make a GET call to a url several times in a for loop.
I am trying to use fetch, but because of the promise/timing situation, I can't figure out how to make it work.
Below is the code and it's entirely possible that the fetch approach doesn't make sense for what I am trying to do. Would appreciate your help either helping me with code or telling me I am idiot and advising an alternative :)
var fromAmt = 100;
var fromOOP = 50;
var fromGM = 50;
var fromCur = "USD"
var toCur = ["USD","EUR","INR","GBP","SGD"];
var adjAmt = [];
async function getConversionAsync(fcur,tcur,amt)
{
let response = await fetch('https://data.fixer.io/api/convert?access_key=xyxyxyxyxyxyxy&from=' + fcur + '&to=' + tcur + '&amount=' + amt);
let data = await response.json()
return data;
}
for (i = 0; i < toCur.length; i++) {
getConversionAsync(fromCur,toCur[0].toString(),fromAmt)
.then(data => display(data));
}
function display(thing){
adjAmt.push(thing.result);
}
document.getElementById("something").innerHTML = adjAmt[0].toString();
In your example, document.getElementById("something").innerHTML = adjAmt[0].toString(); is executed before anything is pushed to adjAmt. You need to wait for the loop calls to finish before displaying a result, and for this you could wrap everything inside an async function.
const fromAmt = 100;
const fromOOP = 50;
const fromGM = 50;
const fromCur = 'USD';
const toCur = ['USD', 'EUR', 'INR', 'GBP', 'SGD'];
const adjAmt = [];
const getConversionAsync = async (fcur, tcur, amt) => {
const response = await fetch(`https://data.fixer.io/api/convert?access_key=xyxyxyxyxyxyxy&from=${fcur}&to=${tcur}&amount=${amt}`);
return response.json();
}
function display(thing) {
adjAmt.push(thing.result);
}
(async () => {
for (i = 0; i < toCur.length; i += 1) {
const data = await getConversionAsync(fromCur, toCur[0], fromAmt);
display(data);
}
document.getElementById('something').innerHTML = adjAmt[0].toString();
})();
Some small changes to make it work without the API call, but you'll want to access the correct index in your loop. I don't know what the exact output you're wanting here but in this case I just joined all the values in the array.
Additionally, the setting of innerHTML needs to be done once all the values are retrieved from the API, so I would even suggest doing that when the loop terminates, or some other "done" type event.
Additionally, you can use Promise.all instead of a loop, which is what I would go with personally.
var fromAmt = 100;
var fromOOP = 50;
var fromGM = 50;
var fromCur = "USD"
var toCur = ["USD", "EUR", "INR", "GBP", "SGD"];
var adjAmt = [];
async function getConversionAsync(fcur, tcur, amt) {
let response = await sampleRequest()
/* let data = await response.json() */
return response;
}
for (i = 0; i < toCur.length; i++) {
const data = getConversionAsync(fromCur, toCur[i].toString(), fromAmt).then(data => {
display(data)
})
}
function display(thing) {
adjAmt.push(thing);
document.getElementById("something").innerHTML = adjAmt.join(', ')
}
function sampleRequest() {
return new Promise((resolve, reject) => {
resolve(Math.round(Math.random() * 1000))
})
}
<div id="something"></div>
I'm trying to get some for Loops running inside a google cloud functions everytime I delete my /users node.
This is the code I'm using
exports.deleteUserAssets = functions.database.ref('/users/{userId}').onWrite((change, context) => {
const beforeData = change.before.val();
const afterData = change.after.val();
const userBuildings = Object.keys(beforeData.isAdmin); // get the buildings of the user stored in the user/userId/isAdmin node .. so far so good
const userId = beforeData.userIDforCloudFunctions; // I'm getting this from a /users/userid/userIDforCloudFucntions node ...so far so good (i've been logging it to confirm)
// making sure it was a delete operation ... so far so good
if (afterData !== null) {
return 0;
}
else {
// on each building
for (var i = 0; i < userBuildings.length; i++) {
let eachBuilding = [userBuildings[i]]
// HERE IS WERE THE PROBLEM IS: Trying to delete all depts + rooms + doors
admin.database().ref('/buildings/' + eachBuilding)
.child("hasDepts")
.once("value")
.then(function(snapshot) { // This is where it goes south – snapshot is returning null
snapshot.forEach(function(childSnapshot) {
var deptKeyString = childSnapshot.key; // will try to get the keys of the departments stored under this space
var deptsOnNode = admin.database().ref('/depts/' + deptKeyString);
deptsOnNode.remove(); // and use the keys to delete each of the depts on depts
});
});
admin.database().ref('/buildings/' + eachBuilding).set({}); // this is working
admin.database().ref('/buildingsUserUid/' + userId + '/' + eachBuilding).remove(); // this is working
}
}
return 0;
});
The snapshot of admin.database().ref('/buildings/' + eachBuilding).child("hasDepts") is returning null.
How can I get to it? Besides admin.database().ref() I've tried to reach it with firebase.database().ref() which is the command/object i use to get this running on frontend functions. I've also tried functions.database() with no result.
Taking in consideration what Doug Stevenson mentioned in his second comment:
exports.deleteUserAssets = functions.database.ref('/users/{userId}').onDelete((change, context, event) => {
const beforeData = change.before.val(); // data before the write (data of all the doors child nodes)
const afterData = change.after.val(); // data before the write (data of all the doors child nodes)
const userBuildings = Object.keys(beforeData.isAdmin); // get the buildings of the user
const userId = beforeData.userIDforCloudFunctions;
// make sure user was deleted
if (afterData !== null) {
return 0;
}
else {
// on each building
for (var i = 0; i < userBuildings.length; i++) {
let eachBuilding = [userBuildings[i]]
// Need to RETURN the whole chain of promises
return admin.database().ref('/buildings/' + eachBuilding)
.child("hasDepts")
.once("value")
.then(function(snapshot) {
console.log(snapshot.val()) // this now works
snapshot.forEach(function(childSnapshot) {
console.log(childSnapshot.val()) // this works as well
var deptKeyString = childSnapshot.key; // get the keys of the departments stored under this space
var deptsOnNode = admin.database().ref('/depts/' + deptKeyString);
// and you can keep on going deeper if you return promises
return deptsOnNode
.child('hasRooms')
.once('value')
.then(function(grandchildSnapshot){
console.log(grandchildSnapshot.val())
grandchildSnapshot.forEach(function(grandGrandchildSnapshot){
var roomKeyString = grandGrandchildSnapshot.key;
var roomsOnDepts = admin.database().ref('/rooms/' + roomKeyString);
admin.database().ref('/roomOwners/' + userId + '/' + roomKeyString).remove();
// and return again here...
return roomsOnDepts
.child('hasDoors')
.once('value')
.then(function(grandgrandGrandchildSnapshot){
grandgrandGrandchildSnapshot.forEach(function(grandgrandGrandchildSnapshot){
var doorKeyString = grandgrandGrandchildSnapshot.key;
var doorsOnRooms = admin.database().ref('/doors/' + doorKeyString);
doorsOnRooms.remove();
let clipOwners = admin.database().ref('/clipOwners/' + doorKeyString);
clipOwners.remove();
})
roomsOnDepts.remove();
})
})
deptsOnNode.remove(); // use the keys to delete the depts on depts main Node
})
});
admin.database().ref('/buildings/' + eachBuilding).set({});
admin.database().ref('/buildingsUserUid/' + userId + '/' + eachBuilding).remove();
});
}
}
return 0;
});