How to import an object and run a function for all properties in module? - node.js

I created a module to store an object with some properties containing array of strings. Once it is imported, I want to get a sample of this array (eg: using lodash / sample). So I do not have to use the 'sample' method every time the module is imported and a property is referenced. Obs.: I want to reference an object and a property, not a function.
/store.js
export default {
foo: [
`This is the first message`,
`This is the second message`,
`This is the third message`
],
bar: [
`This is the message one`,
`This is the message two`,
`This is the message three`
]
};
I want to avoid this:
/file.js
import store from './store';
import sample from 'lodash/sample';
const msg = sample(store.foo);
console.log(msg); // e.g: This is the second message
and use something like this:
/file.js
import store from './store';
const msg = store.foo;
console.log(msg); // e.g: This is the first message

Related

nodejs express server get request log symbols value [duplicate]

I have an object in NodeJS (a socket to be accurate).
When I print it, I see that one of the entries is this:
[Symbol(asyncId)]: 2781 // the numeric value changes
How can I obtain the value of such key?
I've tried socket['[Symbol(asyncId)]'] but got undefined.
The expression socket.[Symbol(asyncId)] would obviously not work.
You will not be able to access it directly by key, unless you have a reference to the actual: Symbol('asyncId'), because every Symbol is unique
The Symbol() function returns a value of type symbol, has static
properties that expose several members of built-in objects, has static
methods that expose the global symbol registry, and resembles a
built-in object class but is incomplete as a constructor because it
does not support the syntax "new Symbol()".
What you can do is loop through the object's own property keys, using Reflect.ownKeys, which will include normal properties & symbols, and then obtain that reference.
You can also use: Object.getOwnPropertySymbols()
function getObject() {
// You don't have access to this symbol, outside of this scope.
const symbol = Symbol('asyncId');
return {
foo: 'bar',
[symbol]: 42
};
}
const obj = getObject();
console.log(obj);
console.log(obj[Symbol('asyncId')]); // undefined
// or Object.getOwnPropertySymbols(obj)
const symbolKey = Reflect.ownKeys(obj)
.find(key => key.toString() === 'Symbol(asyncId)')
console.log(obj[symbolKey]); // 42
NOTE: The object can have multiple keys where key.toString() === 'Symbol(asyncId)', this won't be usual, but be aware, so you may want to use other function other than .find if that's the case.
NOTE II:
You should not change the value of that property, since it's supposed to be for internal access only, even if the property is not read only.
function getObject() {
// You don't have access to this symbol, outside of this scope.
const symbol = Symbol('asyncId');
const symbol2 = Symbol('asyncId');
return {
foo: 'bar',
[symbol]: 'the value I don\'t want',
[symbol2]: 'the value I want'
};
}
const obj = getObject();
const symbolKey = Reflect.ownKeys(obj)
.find(key => key.toString() === 'Symbol(asyncId)')
console.log(obj[symbolKey]); // the value I don't want
console.log('=== All values ===');
Reflect.ownKeys(obj)
.forEach(key => console.log(obj[key]));
Use Object.getOwnPropertySymbols(obj) and iterate over it
You need to store the Symbol in advance and use it as accessor for the object.
Every symbol value returned from Symbol() is unique. A symbol value may be used as an identifier for object properties; this is the data type's only purpose. Some further explanation about purpose and usage can be found in the glossary entry for Symbol.
var asyncId = 42,
symbol = Symbol(asyncId),
object = { [symbol]: 2781 };
console.log(object[symbol]);
console.log(symbol.toString());

Interpolate variable in multiline vanilla javascipt

Recently, I wanted to develop a plugin for javascipt for visual studio code. It's essence is to generate 3 files with template text in them. I stored the template text as a multiline string in a variable, but I never managed to insert the variable interpolation into the multiline string.
Code sample below:
const blocName = await vscode.window.showInputBox({
placeHolder: "Bloc name",
prompt: "Enter the BLoC name",
});
const blocNameLower = blocName.toLowerCase();
const bloc = 'import \'dart:async\';\n\
import \'package:${blocNameLower}_bloc/bloc.dart\'\;\n\
import \'package:meta/meta.dart\';\n\
\n\
part \'${blocNameLower}_event.dart\';\n\
part \'${blocNameLower}_state.dart\';\n\
\n\
class ${blockName}Bloc extends Bloc<${blockName}Event, ${blockName}State> {\n\
${blockName}Bloc() : super(${blockName}Initial()) {\n\
on<${blockName}Event>((event, emit) {\n\
// TODO: implement event handler\n\
});\n\
}\n\
}';
Let's assume input is Test:
Actual behavior:
import 'dart:async';
import 'package:${blocNameLower}_bloc/bloc.dart';
import 'package:meta/meta.dart';
part '**${blocNameLower}**_event.dart';
part '${blocNameLower}_state.dart';
class ${blockName}Bloc extends Bloc<${blockName}Event, ${blockName}State> {
${blockName}Bloc() : super(${blockName}Initial()) {
on<${blockName}Event>((event, emit) {
// TODO: implement event handler
});
}
}
Expected behavior:
import 'dart:async';
import 'package:test_bloc/bloc.dart';
import 'package:meta/meta.dart';
part '**test**_event.dart';
part 'test_state.dart';
class TestBloc extends Bloc<TestEvent, TestState> {
TestBloc() : super(TestInitial()) {
on<TestEvent>((event, emit) {
// TODO: implement event handler
});
}
}
Is there any chance to interpolate variable in multiline line..(as with 'part test_event.dart';) ?

Empty object for Firebase server timestamp

I´m getting an empty object for the admin.firestore.FieldValue.serverTimestamp(), below is the screenshot of the document being stored in Firestore:
Here´s the code for creating the message object (that corresponds to the screenshot above):
import {Message} from "./Message";
import {MessageType} from "./MessageType";
import * as admin from "firebase-admin";
export class TextMessage extends Message {
constructor(objectID: string,
content: string,
authorName: string,
authorID: string,
authorPhotoUrl: string,
createdAt: FirebaseFirestore.FieldValue = admin.firestore.FieldValue.serverTimestamp()) {
super(objectID,
content,
authorName,
authorID,
authorPhotoUrl,
MessageType.text,
createdAt,)
}
}
Here´s where I create the TextMessage object:
const message: TextMessage = new TextMessage(
messageID,
"Cualquier consulta escríbeme un mensaje y estaré para ayudarte",
SUPPORT_NAME,
SUPPORT_USER_ID,
defaultProfilePicture
)
And here´s the Firebase function code in which the code from above is being used:
// Create the chat
const createChatPromise =
firestoreDB
.collection("Chats")
.doc(chatID)
.collection("Messages")
.add(JSON.parse(JSON.stringify(message)))
// Return the method when both functions are finished
return Promise.all(
[
addToFirestorePromise,
addToAlgoliaPromise,
emailPromise,
createCurrentUserInboxPromise,
createSupportInboxPromise,
createChatPromise, ==> This is the promise from above
addUsersIDsPromise
]
).catch(error => functions.logger.log("The error is: " + error.message))
From the object´s documentation:
Returns a sentinel used with set(), create() or update() to include a server-generated timestamp in the written data.
Returns:
The FieldValue sentinel for use in a call to set(), create() or update().
However, I´m using the add function, I don´t know if this is the reason why is not working.
NOTE: I´m using the following versions for firebase admin and functions:
"firebase-admin": "^8.10.0",
"firebase-functions": "^3.7.0",
It's not clear to me why you are using both stringify and parse together like this:
JSON.parse(JSON.stringify(message))
The stringify will destroy the token that internally represents the server timestamp. You're supposed to pass the object to store in Firestore directly to add() or set() - never stringify it.

How can I replace text from a config.json file automatically by a variable in node js

Hi and thank you for your help
I have a config.json file that contains this:
{
"test": {
"hi": {
"text": "Hi ${user.name}"
}
}
}
and I have index.js file that contains:
var config = require('./config.json')
var user = {name: "Test", tag: "#1234")
console.log(`${config.test.hi.text}`) // Output: "Hi ${user.name}"
// Expected output: Hi Test
I want when you change in the config.json the user.name to something like user.tag its automatically replaces him without .replace() function
thank you for your help :D
When using Template literals, the expressions in the placeholders and the text between the backticks (` `) get passed to a function that concatenates the strings into a single string, replacing the values inside $(variable).
This process happens at the time you define the template and cannot be resolved later as you do in your code. Refer to the documentation: Template literals
It would be also a bad coding practise as if the user variable didn't exist in the index.js file it wouldn't give you a compile error, but a nasty runtime error.
The only way to do it is to have your template literal in reach of your variable scope, that means that the template literal can read the variable at the moment it's executed. If you want to have the user instance and the template in different files, you can use a callback function as this:
config.js
const callback = (user) => {
return `Hi ${user.name}`
}
const config = {
callback,
anotherConfig: {
hi: {
example: "This is another config"
}
}
}
export default config;
index.js
import config from './config.js';
const user = {name: "Test", tag: "#1234"};
console.log(config.callback(user))
Output
Hi Test

Angular RxJs TypeError "undefined"

Sorry if this question doesn't make sense, I'm very new to the MEAN stack. I have been trying to get an array from an express middleware to display on an angular frontend. The problem I have been having is even though everything compiles and appears to work I get an error in the console saying "ERROR TypeError: 'this.brackets is undefined'".
This is the code that appears to be the problem
'''
import { Injectable } from "#angular/core";
import { Bracket } from './bracket.model';
import { Subject } from 'rxjs';
import { HttpClient } from '#angular/common/http';
#Injectable({providedIn: 'root'})
private brackets: Bracket[] = [];
private bracketsUpdated = new Subject<Bracket[]>();
constructor(private http: HttpClient) {}
getBracket() {
this.http.get<{message: string, brackets: Bracket[]}>('http://localhost:3000/api/brackets')
.subscribe((bracketData) => {
this.brackets = bracketData.brackets;
this.bracketsUpdated.next([...this.brackets]); // this is the problem line
});
console.log(this.brackets);
}
'''
and this is where the array is coming from
'''
app.use("/api/brackets", (req, res, next)=>{
const bracket= [
{
id: 'alksdfjalskj',
bracketTitle:'bracket from node',
bracketBuyIn: "2",
bracketPlayer1:'name',
bracketPlayer2:'name2',
bracketPlayer3:'name3',
bracketPlayer4:'name4',
bracketPlayer5:'name5',
bracketPlayer6:'name6',
bracketPlayer7:'name7',
bracketPlayer8:'name8'
}
];
console.log(bracket);
res.status(200).json({
message:'Bracket from node',
bracket:bracket
});
});
'''
In vs code it is defined so I'm confused as to why it doesn't work.
EDIT: the bracket referred to is not a naming error. It's referring to an imported model called Bracket
There is a naming error, you have
res.status(200).json({
message:'Bracket from node',
bracket:bracket
});
calling bracket
and in Angular you are using by plural
this.brackets = bracketData.brackets;
bracket(s)
leave either bracket, or brackets and it will work fine
The model you're using in the front-end has nothing to do with the value you receive from the back-end. The model is only there to assert the type of the data you're trying to assign to the variable.
But if you see in the backend
res.status(200).json({
message:'Bracket from node',
bracket:bracket
});
You're clearly assigning the object to a property called bracket, NOT brackets. To be extra sure, the value you receive from the backend is this
{
message:'Bracket from node',
bracket: [{
id: 'alksdfjalskj',
bracketTitle:'bracket from node',
bracketBuyIn: "2",
bracketPlayer1:'name',
bracketPlayer2:'name2',
bracketPlayer3:'name3',
bracketPlayer4:'name4',
bracketPlayer5:'name5',
bracketPlayer6:'name6',
bracketPlayer7:'name7',
bracketPlayer8:'name8'
}]
}
So it's called bracket WITHOUT a s.
Now the front-end part.
this.brackets = bracketData.brackets;
Here the LHS this.brackets for sure abides 100% by the model you've defined. It doesn't jump over any hoops to assign any values that doesn't conform to the model Bracket you've defined. But the RHS bracketData.brackets doesn't care a single percent about your model. It doesn't have to. It comes from the backend, and that's the only thing it abides to.
If you do a console.log(bracketData), you'll see the following
{
message:'Bracket from node',
bracket: [{
id: 'alksdfjalskj',
bracketTitle:'bracket from node',
bracketBuyIn: "2",
bracketPlayer1:'name',
bracketPlayer2:'name2',
bracketPlayer3:'name3',
bracketPlayer4:'name4',
bracketPlayer5:'name5',
bracketPlayer6:'name6',
bracketPlayer7:'name7',
bracketPlayer8:'name8'
}]
}
Now, please take a look again closely. You will never be able to find brackets property. Because you call it bracket in the backend.
So when you try bracketData.brackets there is no data in that property. It might as well be bracketData.magicData for all Javascript cares. It WILL return undefined for undefined properties.

Resources