I am trying to connect to a database using the code below:
import SQLite from 'react-native-sqlite-storage'
var db = SQLite.openDatabase({name : "banco.db", createFromLocation : 1}, this.successCB(), this.errorCB());
errorCB() {
this.setState({message: "I NEED SHOW THE ERROR HERE"});
}
successCB() {
this.setState({message: "SQL executed fine"});
}
How to show the error on the errorCB function?
This is in the documentation example. The error callback will get passed an argument containing the error. You are also not providing the correct value to openDatabase. You should be passing in functions, not trying to call the function.
Copy pasting the relevant parts from the documentation with comments to explain:
// Your error callback function that should take an argument that will contain your error.
errorCB(err) {
console.log("SQL Error: " + err);
// Here you can use err in your setState call.
}
openCB() {
console.log("Database OPENED");
}
// openDatabase should be passed in the functions; openCB and errorCB in this example.
var db = SQLite.openDatabase("test.db", "1.0", "Test Database", 200000, openCB, errorCB);
// What you're doing is incorrect as it's akin to doing this which is wrong.
// var db = SQLite.openDatabase("test.db", "1.0", "Test Database", 200000, openCB(), errorCB());
This is really more of a basic JavaScript question where you need to be able to read the documentation and understand how to use a given API. If you're having trouble with this, I suggest reading up about Higher-Order Functions as it's fundamental to JavaScript.
Edit: To be very direct and answer the comments; this is what your code should look like:
import SQLite from 'react-native-sqlite-storage'
var db = SQLite.openDatabase({name : "banco.db", createFromLocation : 1}, this.successCB, this.errorCB);
// Making the assumption that these are in a class,
// otherwise add the const keyword before them.
// Convert these to arrow functions instead
// so they can more easily be passed as variables.
errorCB = (err) => {
this.setState({message: err});
}
successCB = () => {
this.setState({message: "SQL executed fine"});
}
Given your comments, I'll be very direct here. If you don't understand how functions, Higher-Order Functions, and variables/values work in JavaScript, you are going to have a very difficult time with React Native. Especially so if you are unfamiliar with ES6 syntax. Go through the book in that link or one of the many other great resources for learning the fundamentals of JavaScript before tackling React Native.
I used to open SQLite using following statement
database = SQLite.openDatabase({name: 'my.db', location: 'default'}, (db) => {
db.transaction( tx => {
tx.executeSql(`CREATE TABLE IF NOT EXISTS tableName (columnNames)`);
}, error => {
this.setState({message: error});
});
}, error => {
this.setState({message: error});
});
Hope this will help!
Related
I'm using both client and server from node-opcua, it's working fine apart for error management on the server side when the client tries to write a value and something goes wrong. In order to improve that, I'd like to have an asynchronous setter like in this example:
const wantedValue = namespace.addAnalogDataItem({
componentOf: node,
browseName: `${chamber}${folder}Req`,
nodeId: `s=${chamber}${folder}Req`,
dataType: "Double",
engineeringUnits: settings.unit,
engineeringUnitsRange: settings.range,
value: {
get: () => new Variant({dataType: DataType.Double, value: wrapper.readProgram(chamber, folder)}),
set: async (variant: Variant) => {
const success = await wrapper.writeProgram(chamber, folder, variant.value)
return success ? StatusCodes.Good : StatusCodes.Bad
}
}
})
This naive approach lead to a typer error:
throw new Error("Cannot find StatusCode " + statusCode);
Is there a better way to do that ?
the get and set lambdas are design to be synchronous.
you need to use the callback form with timestamped_get and timestamped_set to achieve what you need.
I have refactor problems because my code dosnt work to the new versions of angular and angularfire.
Error
The line: upload.url = uploadTask.snapshot.downloadURL; is undefined.
Code
uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
// three observers
// 1.) state_changed observer
(snapshot) => {
// upload in progress
upload.progress = (uploadTask.snapshot.bytesTransferred / uploadTask.snapshot.totalBytes) * 100;
console.log(upload.progress);
},
// 2.) error observer
(error) => {
// upload failed
console.log(error);
},
// 3.) success observer
(): any => {
upload.url = uploadTask.snapshot.downloadURL; //?!?!UNDEFINED
upload.name = upload.file.name;
this.saveFileData(upload);
}
);
Questions
I had tried different solutions from stackoverflow but it dosnt really work. Most of the example is also more about how to retrieve the image but i want to set the variable upload.url to a value.
Another question:
I'm new to angular and web. Will it take long time to change it to firestore? The code is based on realtime firebase.
To get the downloadURL, you have to call the getDownloadURL() method of the Storage Reference Object.
Try this:
uploadTask.snapshot.ref.getDownloadURL()
.subscribe(url => console.log(url))
Is there a way to update a part of the URL reactively without using FlowRouter.go() while using React and react-layout?
I want to change the value in the document that is used to get the document from the DB. For example, if I have a route like ~/users/:username and update the username field in the document, I then have to user FlowRouter.go('profile', {data}) to direct the user to that new URL. The "old" route is gone.
Below is the working version I have, but there are two issues:
I have to use FlowRouter.go(), which is actually a full page refresh (and going back would be a 404).
I still get errors in the console because for a brief moment the reactive data for the component is actually wrong.
Relevant parts of the component are like this:
...
mixins: [ReactMeteorData],
getMeteorData() {
let data = {};
let users = Meteor.subscribe('user', {this.props.username});
if (user.ready())
data.user = user;
return data;
}
...
updateName(username) {
Users.update({_id:this.data.user._id}, {$set:{username}}, null, (e,r) => {
if (!e)
FlowRouter.go('profile', {username});
});
},
...
The route is like this:
FlowRouter.route('/users/:username', {
name: 'profile',
action(params) {
ReactLayout.render(Main, {content: <UserProfile {...params} />});
}
});
The errors I get in the console are:
Exception from Tracker recompute function:
and
TypeError: Cannot read property '_id' of undefined
I am using the boto DynamoDBV2 interface for a script to create and populate a table in the DynamoDB. My code for it looks something like this -
my_table = Table.create(table_name, schema=[HashKey('key', data_type=STRING)], connection = self.connection)
my_table.put_item(data={
'key': 'somekey',
'value': value
})
I have created the connection, and when I run it, the table is created properly and I can see it in the AWS console. But I am getting the error "Requested Resource not found" when trying to put values in the table.
I also tried reading table separately and then insert values like this -
Table.create(table_name, schema=[HashKey('key', data_type=STRING)], connection = self.connection)
my_table = Table(table_name, self.connection)
my_table.put_item(data={
'key': 'somekey',
'value': value
})
but still getting the same error on the second line. What am I missing ?
The problem is that you need to wait a little bit after the table is created before inserting items. You can use the waitFor() event to find when the table finishes to be created.
Example with AWS Node SDK:
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB();
const createTableParams = {
// parameters...
}
dynamodb.createTable(createTableParams, (err, data) => {
if (err) return console.log(err, err.stack);
const params = {
TableName: 'MY_TABLE'
};
dynamodb.waitFor('tableExists', params, (err, data) => {
if (err) console.log(err, err.stack);
else insertData();
});
});
Your table will not be immediately ready on creation, you have to wait for it to become active before writing to it. I found a Java code sample that illustrates how to do this, but the problem is not language-specific, it applies to any DynamoDB client.
You can see this in the AWS Management Console as the "Status" of the table, to confirm or deny this theory.
Meteor Collections have a transform ability that allows behavior to be attached to the objects returned from mongo.
We want to have autopublish turned off so the client does not have access to the database collections, but we still want the transform functionality.
We are sending data to the client with a more explicit Meteor.publish/Meteor.subscribe or the RPC mechanism ( Meteor.call()/Meteor.methods() )
How can we have the Meteor client automatically apply a transform like it will when retrieving data directly with the Meteor.Collection methods?
While you can't directly use transforms, there is a way to transform the result of a database query before publishing it. This is what the "publish the current size of a collection" example describes here.
It took me a while to figure out a really simple application of that, so maybe my code will help you, too:
Meteor.publish("publicationsWithHTML", function (data) {
var self = this;
Publications
.find()
.forEach(function(entry) {
addSomeHTML(entry); // this function changes the content of entry
self.added("publications", entry._id, entry);
});
self.ready();
});
On the client you subscribe to this:
Meteor.subscribe("publicationsWithHTML");
But your model still need to create a collection (on both sides) that is called 'publications':
Publications = new Meteor.Collection('publications');
Mind you, this is not a very good example, as it doesn't maintain the reactivity. But I found the count example a bit confusing at first, so maybe you'll find it helpful.
(Meteor 0.7.0.1) - meteor does allow behavior to be attached to the objects returned via the pub/sub.
This is from a pull request I submitted to the meteor project.
Todos = new Meteor.Collection('todos', {
// transform allows behavior to be attached to the objects returned via the pub/sub communication.
transform : function(todo) {
todo.update = function(change) {
Meteor.call('Todos_update', this._id, change);
},
todo.remove = function() {
Meteor.call('Todos_remove', this._id);
}
return todo;
}
});
todosHandle = Meteor.subscribe('todos');
Any objects returned via the 'todos' topic will have the update() and the remove() function - which is exactly what I want: I now attach behavior to the returned data.
Try:
let transformTodo = (fields) => {
fields._pubType = 'todos';
return fields;
};
Meteor.publish('todos', function() {
let subHandle = Todos
.find()
.observeChanges({
added: (id, fields) => {
fields = transformTodo(fields);
this.added('todos', id, fields);
},
changed: (id, fields) => {
fields = transformTodo(fields);
this.changed('todos', id, fields);
},
removed: (id) => {
this.removed('todos', id);
}
});
this.ready();
this.onStop(() => {
subHandle.stop();
});
});
Currently, you can't apply transforms on the server to published collections. See this question for more details. That leaves you with either transforming the data on the client, or using a meteor method. In a method, you can have the server do whatever you want to the data.
In one of my projects, we perform our most expensive query (it joins several collections, denormalizes the documents, and trims unnecessary fields) via a method call. It isn't reactive, but it greatly simplifies our code because all of the transformation happens on the server.
To extend #Christian Fritz answer, with Reactive Solution using peerlibrary:reactive-publish
Meteor.publish("todos", function() {
const self = this;
return this.autorun(function(computation) {
// Loop over each document in collection
todo.find().forEach(function(entry) {
// Add function to transform / modify each document here
self.added("todos", entry._id, entry);
});
});
});