Firebase database remove() "is not a function" - firebase-realtime-database

This code works:
firebase.database().ref($scope.language).orderByChild('word').equalTo($scope.word).once('value')
.then(function(snapshot) {
console.log(snapshot.val());
})
It logs the object and its key.
This code doesn't work:
firebase.database().ref($scope.language).orderByChild('word').equalTo($scope.word).remove()
.then(function(snapshot) {
console.log("Removed!");
})
The error message is:
TypeError: firebase.database(...).ref(...).orderByChild(...).equalTo(...).remove is not a function
The documentation makes remove() look simple. What am I missing?

You can only load data once you know its specific location in the JSON tree. To determine that location, you need to execute the query and loop through the matching results:
firebase.database().ref($scope.language).orderByChild('word').equalTo($scope.word).once("value").then(function(snapshot) {
snapshot.forEach(function(child) {
child.ref.remove();
console.log("Removed!");
})
});
If you only want to log after all have been removed, you can use Promise.all():
firebase.database().ref($scope.language).orderByChild('word').equalTo($scope.word).once("value").then(function(snapshot) {
var promises = [];
snapshot.forEach(function(child) {
promises.push(child.ref.remove());
})
Promise.all(promises).then(function() {
console.log("All removed!");
})
});

This is Frank's first code block with another closure. Without the closure the record is removed from the database but then there's an error message:
Uncaught (in promise) TypeError: snapshot.forEach(...).then is not a function
Adding a closure fixes the error message.
firebase.database().ref($scope.language).orderByChild('word').equalTo($scope.word).once("value").then(function(snapshot) {
snapshot.forEach(function(child) {
child.ref.remove();
}); // a closure is needed here
}).then(function() {
console.log("Removed!");
});

Related

trying to store image as base64 and using it

I have a block of code that I found online and it seems to be working and not working at the same time. I think its probably my lack of understanding but I cant seem to get it to work the way I want it.
selectPicture() {
let context = imagepicker.create({
mode: "single" // use "multiple" for multiple selection
});
var imageBase64
context
.authorize()
.then(function() {
return context.present();
})
.then(function(selection) {
selection.forEach(function(selected) {
imageSourceModule.fromAsset(selected).then((imageSource) => {
imageBase64 = imageSource.toBase64String("jpg",60);
console.log("Image saved successfully!")
console.log(imageBase64)
console.log("test test") //runs fine
this.image = "~/assets/images/account/camera.png" //cant seem to run
console.log("test test 2")
}).catch(function (e) {
// process error
console.log("got error 1")
});
})
}).catch(function (e) {
// process error
console.log("got error 2")
});
},
Within the imageSourceModule.fromAsset(selected).then((imageSource), I was trying to save the base64 info in another variable but cant seem to do anything within other than console log a string. When I run this.image = "~/assets/images/account/camera.png" (just a placeholder, even calling a method does not work too) for example it catches an error.
What could the problem be? thank you!
UPDATE
I changed console.log("got error 1") to log the actual update and what i got was:
undefined is not an object (evaluating 'this.image = "~/assets/images/account/camera.png"')*
I now think that theres a problem with my understanding calling variable outside. My variable 'image' is within the script at
data() {
return {
image : ""
}
}
first of all check what this variable is, because you do not use es6 arrow functions, so this is probably not the vue instance.
the second thing: when you change vue-variables asynchronously use the $set method, like: this.$set(this, 'image', '~/assets/images/account/camera.png')

Apollo GraphQL: Child Component Re-Runs Parent Query?

I've got a parent component with an Apollo query attached:
const withData = graphql(MY_QUERY, {
options({ userID }) {
return {
variables: { _id: userID}
};
},
props({ data: { loading, getOneUser } }) {
return { loading, getOneUser };
},
});
export default compose(
withData,
withApollo
)(NavigatorsList);
export { getOneUser_QUERY };
I've got a child component called userPhoto embedded in the render function:
return (
<div>
<userPhoto />
[.....]
</div>
)
Without the child component, the withData GraphQL function runs twice, once for loading == true, and one more time with the data returned.
With the child component included, the withData GraphQL function runs three times. The third time getOneUser is undefined and my component throws an error.
How can I correct this?
Thanks in advance to all for any info.
Fixed. There was a syntax error in the child component that wasn't throwing an error, but was causing the query to run twice + assorted other anomalies.

Wait for future to complete

I use my postgres database query to determine my next action. And I need to wait for the results before I can execute the next line of code. Now my conn.query returns a Future but I can't manage to get it async when I place my code in another function.
main() {
// get the database connection string from the settings.ini in the project root folder
db = getdb();
geturl().then((String url) => print(url));
}
Future geturl() {
connect(db).then((conn) {
conn.query("select trim(url) from crawler.crawls where content IS NULL").toList()
.then((result) { return result[0].toString(); })
.catchError((err) => print('Query error: $err'))
.whenComplete(() {
conn.close();
});
});
}
I just want geturl() to wait for the returned value but whatever I do; it fires immediately. Can anyone point me a of a piece of the docs that explains what I am missing here?
You're not actually returning a Future in geturl currently. You have to actually return the Futures that you use:
Future geturl() {
return connect(db).then((conn) {
return conn.query("select trim(url) from crawler.crawls where content IS NULL").toList()
.then((result) { return result[0].toString(); })
.catchError((err) => print('Query error: $err'))
.whenComplete(() {
conn.close();
});
});
}
To elaborate on John's comment, here's how you'd implement this using async/await. (The async/await feature was added in Dart 1.9)
main() async {
try {
var url = await getUrl();
print(url);
} on Exception catch (ex) {
print('Query error: $ex');
}
}
Future getUrl() async {
// get the database connection string from the settings.ini in the project root folder
db = getdb();
var conn = await connect(db);
try {
var sql = "select trim(url) from crawler.crawls where content IS NULL";
var result = await conn.query(sql).toList();
return result[0].toString();
} finally {
conn.close();
}
}
I prefer, in scenarios with multiple-chained futures (hopefully soon a thing of the past once await comes out), to use a Completer. It works like this:
Future geturl() {
final c = new Completer(); // declare a completer.
connect(db).then((conn) {
conn.query("select trim(url) from crawler.crawls where content IS NULL").toList()
.then((result) {
c.complete(result[0].toString()); // use the completer to return the result instead
})
.catchError((err) => print('Query error: $err'))
.whenComplete(() {
conn.close();
});
});
return c.future; // return the future to the completer instead
}
To answer your 'where are the docs' question: https://www.dartlang.org/docs/tutorials/futures/
You said that you were trying to get your geturl() function to 'wait for the returned value'. A function that returns a Future (as in the example in the previous answer) will execute and return immediately, it will not wait. In fact that is precisely what Futures are for, to avoid code doing nothing or 'blocking' while waiting for data to arrive or an external process to finish.
The key thing to understand is that when the interpreter gets to a call to then() or 'catchError()' on a Future, it does not execute the code inside, it puts it aside to be executed later when the future 'completes', and then just keeps right on executing any following code.
In other words, when using Futures in Dart you are setting up chunks of code that will be executed non-linearly.

AngularJS serverside variable to ng-init and methods sequence

I´v got a "detail" view and a controller that initilizes data with an id.
My view:
<div ng-app="AFApp" ng-controller="AgentCtrl" ng-init="init('#Model.Id')">
My controller:
$scope.id;
$scope.agent = {};
$scope.init = function (id) {
$scope.id = id;
getAgent();
getAgentStatus();
getSystemInfo();
getActions();
};
The problem is that the method "getAgentStatus();" gets executed before "getAgent();". The "getAgentStatus" needs the $scope.agent data that "getAgent" provides. The function getAgentStatus has an attached timer, and it gets the value as the timer elepses but not in the init function. Can someone please help me out with the method execution sequence in angular controllers and how the id parameter is provided the best possible way.
See methods below:
function getAgent() {
agentDataFactory.getAgent($scope.id)
.success(function (data) {
$scope.agent = data;
})
.error(function (error) {
console.log('Unable to load data: ' + error.message);
});
};
function getAgentStatus() {
if (typeof ($scope.agent.ServiceUrl) == 'undefined' || $scope.agent.ServiceUrl == null) {
console.log('getAgentStatus: ServiceUrl is undefined ' + JSON.stringify($scope.agent));
}
agentDataFactory.getAgentStatus($scope.agent.ServiceUrl)
.success(function (data) {
$scope.agent.CurrentStatus = data.Status;
$scope.agent.CurrentInterval = data.Interval;
})
.error(function (error) {
console.log('Unable to load data: ' + error);
});
$timeout(getAgentStatus, 3000);
};
You can pass getAgentStatus() as a callback parameter to getAgent() and have it executed in the success callback (at which point agent will be defined):
function getAgent(callback) {
agentDataFactory.getAgent($scope.id)
.success(function (data) {
$scope.agent = data;
callback && callback();
})
.error(function (error) {
console.log('Unable to load data: ' + error.message);
});
};
$scope.init = function (id) {
$scope.id = id;
getAgent(getAgentStatus);
getSystemInfo();
getActions();
};
Short explanation:
Some highlights first:
agentDataFactory.getAgent($scope.id).success(...).error(...);:
Creates a promise (which will be resolved) asynchronously and registers two callbacks, one if the promise is successfully resolved and one for the case of an error.
.success(function (data) { $scope.agent = data; }):
Registers a callbackfor when the promise is successfully resolved. When (and if) that happens, $scope.agent will be set.
function getAgentStatus() { if (typeof ($scope.agent.ServiceUrl...:
Tries to access some properties of $scope.agent and thus requires the object to be defined.
So, what happens with your code:
getAgent() is gets called.
[$scope.agent is undefined]
A promise is created that when resolved will set $scope.agent.
[$scope.agent is undefined]
getAgent() returns and getAgentStatus() is called.
[$scope.agent is undefined]
getAgentStatus() tries to access $scope.agent's properties and fails.
[$scope.agent is undefined]
The promise created in step 2 is resolved and its success callback get executed.
[$scope.agent is finally defined]
My version of the code ensures that getAgentStatus() is not executed before the promise is resolved and thus $scope.agent is defined:
getAgent() is gets called.
[$scope.agent is undefined]
A promise is created that when resolved will set $scope.agent.
[$scope.agent is undefined]
getAgent() returns and other functions get called (e.g. getSystemInfo(), getActions(), etc.).
[$scope.agent is undefined]
The promise created in step 2 is resolved and its success callback get executed.
[$scope.agent is finally defined]
Only now does getAgentStatus() get called and it works as expected since...
[$scope.agent is defined]
Take a look at the $q service for more info on Angular promises.

Checking success, error and complete statuses in ajax script

I have below script in asp.net mvc:
$.ajax({
url: "/MyController/MyAction/",
type: 'POST',
data: $("#Myform").serialize(),
success: function () {
// Do something
},
error: function () {
// Do something
},
complete: function () {
// Do something
},
beforeSend: function () {
// Do someting
}
});
This script calls to an action in the controller. The controller performs some actions and sometimes things go ok or not. If things went ok, I want success and complete options in the script get executed.No problem until here, but if in the controller there is an error or something I want to tell the script: "hey, there is an error!" and then the error option in the script to be executed. How to do this? Do I have to return something from the controller to the script to indicate an error has been generated in order to error option in the script gets executed?
Set the HTTP status code to 4xx or 5xx in the controller.
That will make you end up in the error callback.
As far as the AJAX request goes an error is an transfer/network error getting the page.
If you want to return an error either return it in the data then parse that and execute the error function inside the success part if you detect an error. Or as, Johan says, return an HTTP error code from the server.
Use try catch in your action like,
public ActionResult Sample()
{
try
{
return Json(new{status="success"},JsonRequestBehavior.AllowGet);
}
catch(Exception ex)
{
return Json(new{status="failed"},JsonRequestBehavior.AllowGet);
}
}
In your ajax call success check with condition like,
if(data.status=='success')
{
alert('All Happies');
}
else
{
alert('error came');
}
Hope this helps.

Resources