I got this config.json file :
"signs_table": {
"id_field": "dummy_id_field_name",
"prop" : "dummy_prop_name"
...
}
This file contains tons of configuration for huge amount of tables stored in a database. Every table has different field name but the configuration for my code is the same for each table (an Id field name, different property fields, but of course fields name changes from table to table).
So, in my code, I am getting a data object and I want to be able to destructs it to dynamically named properties (from the configuration) like so :
const { dummy_id_field_name, dummy_prop_name} = this.props.data
but this is hard coded way. I would like to load the named properties based on the configuration file.
something like :
const IdField = config.get("signs_table").id_field // this will retrieve the actual field name from config.json I want to be able to pass it through the destructuring operation
const PropField = config.get("signs_table").prop
const { IdField , PropField } = data
Here the config.get("signs_table") line is a from a class method that manage my config.json file...it basically retrieves the property.
So far I found this usefull approach :
ES6 — How to destructure from an object with a string key?
But this does not help me since I need to first retrieve the field name from the configuration file...
Any Idea ?
You cannot avoid fetching the field names from the config files first:
const { id_field: IdField, pro: PropField } = config.get("signs_table"); // this will retrieve the actual field names from config.json
Then, afterwards you can use those as computed property names when destructuring your actual data:
const { [IdField]: idValue , [PropField]: propValue } = this.props.data;
console.log(idValue, propValue);
You can de-structure arbitrary property names as I'll show below, but the question is why are you forcing yourself into a syntax you are unfamiliar with. You should stick with the readable and straightforward approach instead of some fancy convoluted method.
const idField = config.get("signs_table").id_field; // this will retrieve the actual field name from config.json I want to be able to pass it through the destructuring operation
const propField = config.get("signs_table").prop;
const { [idField]: idValue, [propField]: propValue } = data;
It would be more straightforward to simply avoid the de-structuring altogether and access the fields directly.
const idField = config.get("signs_table").id_field; // this will retrieve the actual field name from config.json I want to be able to pass it through the destructuring operation
const propField = config.get("signs_table").prop;
const idValue = data[idField];
const propValue = data[propField];
Related
I am new to Vue/Typescript and was struggling with the following error.
I have a class called UploadableFile like this:
export class UploadableFile {
file: File;
dimensions: Ref;
price: ComputedRef<number>;
...
constructor(file: File) {
this.file = file;
this.dimensions = Ref({width: file.width, height: file.height})
this.price = computed((): number => {
return computePrice(this.dimensions);
});
}
}
This class represents a image file that we can upload. Since the user will be able to modify the dimensions of it, I set the dimensions as a ref. Plus since the price depends on the dimensions, I use a computed Ref calling a function computePrice, that returns a number.
In the main App, I have a function that defines an empty ref like this:
const files = ref<UploadableFile[]>([]);
This variable will contain the files that the user upload when he clicks on a button. Initially it is empty since the user didnt upload anything.
When the user clicks on the button, the following functions is called:
function addFiles(newFiles: File[]){
const newUploadableFiles = newFiles
.map((file) => new UploadableFile(file))
files.value = newUploadableFiles;
}
So it transform an array of HTML files to an array of UploadableFile. The transformation of the array works well but the problem arises when we assign this new array to the ref.
files.value = newUploadableFiles;
I got the following error:
Types of property 'price' are incompatible.
Type 'ComputedRef' is not assignable to type 'number'.
I feel like the price ref is somehow unpacked but can't figure out a solution except to transform the type of the price like this:
price: ComputedRef<number|any>;
With this, everything works but now the type of price is Any where it should be number.
Any suggestion ?
The generic paramater UploadableFile[] passed into the ref function call is internally unwrapped using the UnwrapRef type, which results in the error.
If you change your files definition to the following:
const files: Ref<UploadableFile[]> = ref([]);
this doesn't happen and the assignment works just fine.
I have a directory containing all display types and I need to expose these types via an API. This set of display types will grow significantly over this application's lifecycle, so it'd be nice if adding a new type didn't require adding new code to our service layer.
So in a scenario where a subdir src/domain/types/ contains Type1.js, Type2.js, Type3.js, and Type4.js, is it possible to have a piece of code that instantiates all these types and adds those to some array? Something like:
// I know this line won't work, but you get the idea
const dir = require('../src/domain/types/')
getAllDisplayTypes() {
const types = []
for (const type in dir) {
// auto-magically create new type
types.push(someMagicallyCreatedType)
}
return types
}
where types would be an array where each entry is a set of default values created in the constructor of TypeX.js.
Alternatively, if you have a creative way to expose a set of domain object definitions, I'm all ears.
Figured it out. Using a package called require-dir that let's you require an entire directory, I was able to use some JS devilry to get this working:
const require_dir = require('require-dir')
const allTypes = require_dir('../domain/types/')
// ...
getDisplayTypes() {
const types = {}
for (const typeName of Object.keys(allTypes)) {
const typeConstructor = allTypes[typeName]
const typeInstance = new typeConstructor()
types[typeName] = typeInstance
}
return types
}
The full path for my reference looks like this
data/-KdWI6HAF0_wh9-NTEpe/films/thelobster/rating
and I can set it with
firebase.database().ref('data/-KdWI6HAF0_wh9-NTEpe/films/thelobster/rating')
.set(5);
The problem is that both the keys -KdWI6HAF0_wh9-NTEpe and thelobster are dynamic.
It makes it more difficult than it should be, is there any way to build this with just the -KdWI6HAF0_wh9-NTEpe key and make the film name a wildcard? Oris there a better way I am missing?
You can use Firebase's child() method:
firebase.database().ref('data').child(key).child('films').child(filmKey).child('rating').set(5);
Alternatively you can use ES6 string interpolation:
firebase.database().ref(`data/${key}/films/${filmKey}/rating`).set(5);
Firebase returns 'key' which is the id used to reference your object. Something like this.
var ref = firebase.database().ref("users/ada");
ref.once("value")
.then(function(snapshot) {
var key = snapshot.key; // "ada"
var childKey = snapshot.child("name/last").key; // "last"
});
You can read more about it here.
For 'thelobster', you can console.log() the data that comes from firebase, check the location of the dynamically changing 'thelobster', set it to a variable, and use the variable in your url.
Because I don't know how your incoming data looks like, I can't provide you with that code.
This is my first app project using Google Cloud Functions & Firebase. I'm trying to find away to get a single value of the array that I'm returning and compare it to a set variable and if it matches, update another child's value in that same account.
My App users can add records to the database under their login/user_id that is stored in the database. I'm trying to get a list of the "RecordName" that is a child under that login/user_id that every user has stored in their account.
So basically every "RecordName" in the entire database. When I want to run specials for those records, I need to match the name of that record to the name of the record I have on special and if there is a match, update another child value under that user's account ("special" = true.). This way, when they load their app next time, I have it highlighting that record so they know it's on special.
When I use..
const ref = admin.database().ref(`/store`);
...with the following code...
ref.on('value', function(snapshot) {
// puts ALL items of the object into array using function ..
console.log(snapshotToArray(snapshot));
});
... and the function...
function snapshotToArray(snapshot) {
var returnArr = [];
snapshot.forEach(function(childSnapshot) {
var item = childSnapshot.val();
item.key = childSnapshot.key;
returnArr.push(item);
});
return returnArr;
};
... I get the entire array just as it is in the database:
-store
-{ones_users_id}
-recordname: value1
-special: false
-{anothers_users_id}
-recordname: value2
-special: false
ect. ect.
If my record on special is called, "Newbie Record", what would be the best way to take out every individual value for the key: "recordname" from the array, compare each one to var = "Newbie Record" and if they match, update the value of the key: "special" to be true?
I'm new to JSON and NodeJS, I've been searching on here for answers and can't find exactly what I'm looking for. Your feedback would be very helpful.
It sounds like you're looking to query your database for nodes that have "recordname": "Newbie Record" and update them.
An easy way to do this:
const ref = admin.database().ref(`/store`);
const query = ref.orderByChild("recordname").equalTo("Newbie Record");
query.once('value', function(snapshot) {
snapshot.forEach(function(child) {
child.ref.update({ special: true })
});
});
Main differences with your code:
We now use a query to read just the nodes that we want to modify.
We now use once() to read the data only once.
We loop over the children of the snapshot, since a query may result in multiple nodes.
We use the reference of each child and then update its special property.
I recommend reading a bit more about Firebase queries in the documentation.
I have getters defined within the property definition of my model, they look like this:
timeReported: {
type: DataTypes.DATE,
defaultValue: Sequelize.NOW,
get() {
const input = this.getDataValue('timeReported')
const output = moment(input).valueOf()
return output
},
set(input) {
var output = moment(input).toDate()
this.setDataValue('timeReported', output)
},
validate: {
isBefore: moment().format('YYYY-MM-DD')
}
}
I have tried adding the getter to getterMethods in the options instead of within the property:
getterMethods: {
timeReported: function () {
debugger
const input = this.getDataValue('timeReported')
const output = moment(input).valueOf()
return output
}
}
I find that the setters are executed correctly when I save because I use timestamps as the request payload. I also find that validations work correctly.
Interestingly the afterFind hook is called correctly and it does show that customGetters have been registered as existing on my model.
However, when I call the find method on my model like this:
const {dataValues} = yield models.Reporting.findOne({
where: {
reportNo: reportNo
}
})
My getter methods are not invoked to transform my data for presentation. How do I invoke these methods on the data fetched from the db before I can access it.
I have tried adding the raw:false property to the queryOptions along with where. That did not work.
NOTE: I fetch my data using co, I have to retrieve the dataValues property from the model. None of the examples seem to be using the property.
When using Sequelize,one should not use dataValues property directly as I did. This will give me access to the underlying data stored in the table without invoking the getters.
To invoke all the getter functions on the entire instance:
const data = instance.get()
This will also populate any virtual fields that one has defined in the model.
To invoke the getter for an individual property:
const propValue = instance.get('timeReported')