I have several JavaScript files that I create enums. for example:
source.enum.js
const enumUtils = require('../enum.utils');
const EmailAddressesSourceType = enumUtils.createEnum([
['DIRECTORY', 'directory'],
['FILE', 'file'],
['ARRAY', 'array']
]);
module.exports = { EmailAddressesSourceType };
The enum.utils.js is just a file that do the simple function of creating an enum from array:
class EnumUtils {
constructor() { }
// This method takes a map of elements and converts them to freeze objects (an enum-like object).
createEnum(mapItems) {
if (!mapItems || mapItems.length <= 0) {
throw new Error(`No array received: ${mapItems} (1000000)`);
}
const mapList = new Map([...mapItems]);
const symbolMap = {};
mapList.forEach((value, key) => { symbolMap[key] = value; });
return Object.freeze(symbolMap);
}
}
const enumUtils = new EnumUtils();
module.exports = enumUtils;
Now since I have 5-6 js files with enums, I want to avoid 'const enumUtils = require('../enum.utils');' in each of them, and do it all together in index.js file, something like this:
const { EmailAddressStatus, EmailAddressType, SendEmailStepName } = require('./files/emailAddress.enum');
const { Placeholder } = require('./files/placeholder.enum');
const { EmailAddressesSourceType } = require('./files/sources.enum');
const { Mode, Status, Method } = require('./files/system.enum');
const { StatusIcon, Color, ColorCode } = require('./files/text.enum');
const createEnum = (mapItems) => {
if (!mapItems || mapItems.length <= 0) {
throw new Error(`No array received: ${mapItems} (1000000)`);
}
const mapList = new Map([...mapItems]);
const symbolMap = {};
mapList.forEach((value, key) => { symbolMap[key] = value; });
return Object.freeze(symbolMap);
};
module.exports = {
createEnum(Color), createEnum(ColorCode), createEnum(EmailAddressStatus), createEnum(EmailAddressType), createEnum(EmailAddressesSourceType),
createEnum(Method), createEnum(Mode), createEnum(Placeholder), createEnum(SendEmailStepName), createEnum(Status), createEnum(StatusIcon)
};
But, there are compilation error in:
module.exports = {
createEnum(Color), createEnum(ColorCode), createEnum(EmailAddressStatus), createEnum(EmailAddressType), createEnum(EmailAddressesSourceType),
createEnum(Method), createEnum(Mode), createEnum(Placeholder), createEnum(SendEmailStepName), createEnum(Status), createEnum(StatusIcon)
};
My question is, there is a workaround so enable me to reduce the 'const enumUtils = require('../enum.utils');' in each file of the enums js file?
Thanks!
UPDATE 1
The error I'm getting is this:
The current status of the file (before I was trying to refactor) - It works OK:
index.js
const { EmailAddressStatus, EmailAddressType, SendEmailStepName } = require('./files/emailAddress.enum');
const { Placeholder } = require('./files/placeholder.enum');
const { EmailAddressesSourceType } = require('./files/sources.enum');
const { Mode, Status, Method } = require('./files/system.enum');
const { StatusIcon, Color, ColorCode } = require('./files/text.enum');
module.exports = {
Color, ColorCode, EmailAddressStatus, EmailAddressType, EmailAddressesSourceType,
Method, Mode, Placeholder, SendEmailStepName, Status, StatusIcon
};
This guy, guy-incognito, solved for me the issue. Now it works like a charm. Thanks man!
const { EmailAddressStatus, EmailAddressType, SendEmailStepName } = require('./files/emailAddress.enum');
const { Placeholder } = require('./files/placeholder.enum');
const { EmailAddressesSourceType } = require('./files/sources.enum');
const { Mode, Status, Method } = require('./files/system.enum');
const { StatusIcon, Color, ColorCode } = require('./files/text.enum');
const createEnum = (mapItems) => {
if (!mapItems || mapItems.length <= 0) {
throw new Error(`No array received: ${mapItems} (1000000)`);
}
const mapList = new Map([...mapItems]);
const symbolMap = {};
mapList.forEach((value, key) => { symbolMap[key] = value; });
return Object.freeze(symbolMap);
};
module.exports = {
Color: createEnum(Color),
ColorCode: createEnum(ColorCode),
EmailAddressStatus: createEnum(EmailAddressStatus),
EmailAddressType: createEnum(EmailAddressType),
EmailAddressesSourceType: createEnum(EmailAddressesSourceType),
Method: createEnum(Method),
Mode: createEnum(Mode),
Placeholder: createEnum(Placeholder),
SendEmailStepName: createEnum(SendEmailStepName),
Status: createEnum(Status),
StatusIcon: createEnum(StatusIcon)
};
Related
I'm trying to create an anti-crash function, but got confused at the moment that the channel does not return the author. How can I get the author in another way?
I tried to connect to AuditLogEvent, but it didn't work
My code:
const { AuditLogEvent } = requier('discord.js')
const usersMap = new Map();
const LIMIT = 3;
const TIMES = 10000
bot.rest.on('channelDelete', async channel => {
const fetchedLogs = await channel.guild.fetchAuditLogs({
limit: 1,
type: AuditLogEvent.ChannelDelete,
})
const deletionLog = fetchedLogs.entries.first();
const { executor, target } = deletionLog
if(channel.guild.id != "940990129307263046") return
if(usersMap.has(executor.id)) {
const userData = usersMap.get(executor.id);
const { lastDelete, timer } = userData;
let deleteCount = userData.deleteCount;
const tim = channel.createdTimestamp - lastDelete.createdTimestamp
if(tim > TIMES) {
usersMap.delete(executor.id)
} else {
++deleteCount;
if(parseInt(deleteCount) === LIMIT) {
executor.ban()
}
}
}
})
I'm working on standing up a simple Relay/GraphQL app using Node.
At the root level, I have a connection called 'notes' that paginates all notes in the database. On my user object, I have a notes connection that paginates all notes that user has created.
const rootNotesId = ConnectionHandler.getConnectionID('client:root', 'RootNotesConnection_notes');
const userNotesId = ConnectionHandler.getConnectionID(queryData?.me?.id, 'UserNotesConnection_notes');
const rootNotes = usePaginationFragment(graphql `
fragment NotesRoot_notes on Query #refetchable(queryName: "NotesRootQuery") {
notes(first: $count, after: $cursor) #connection(key: "RootNotesConnection_notes") {
edges {
node {
...Note_note
}
}
}
}
`, queryData);
const userNotes = usePaginationFragment(graphql`
fragment NotesUser_notes on Query #refetchable(queryName: "NotesUserQuery") {
me {
id
notes(first: $count, after: $cursor) #connection(key: "UserNotesConnection_notes") {
edges {
node {
...Note_note
}
}
}
}
}
`, queryData);
How do I add or delete a note to both connections at once client-side? I have two different edge types and I thought this code would work:
const [commit, isInFlight] = useMutation(graphql `
mutation NotesCreateMutation($input: createNoteInput!) {
createNote(input: $input) {
noteEdge {
cursor,
node {
id
user {
username
}
content
}
}
}
}
`);
const handleButtonClick = () => {
if (!isInFlight) {
commit({
variables: {
input: {
content: newNoteInput
}
},
updater: store => {
const rootCon = ConnectionHandler.getConnection(store.get('client:root'), 'RootNotesConnection_notes');
const userCon = ConnectionHandler.getConnection(store.get(userId), 'UserNotesConnection_notes');
const payload = store.getRootField('createNote');
const newEdge = payload.getLinkedRecord('noteEdge');
const newNote = newEdge.getLinkedRecord('node');
debugger;
const newRootEdge = ConnectionHandler.createEdge(store, rootCon, newNote, 'QueryNotesEdge');
const newUserEdge = ConnectionHandler.createEdge(store, userCon, newNote, 'UserNotesEdge');
ConnectionHandler.insertEdgeAfter(rootCon, newRootEdge);
ConnectionHandler.insertEdgeAfter(userCon, newUserEdge);
}
});
setNewNoteInput('');
}
}
The only thing I can find in my debugging is that the cursor never gets set for the new edge. Stepping through this code in the debugger reveals that all variables before newRootEdge resolve just fine
This worked. Thanks to this thread for a good workaround: https://github.com/facebook/relay/issues/2761
const handleButtonClick = () => {
if (!isInFlight) {
commit({
variables: {
input: {
content: newNoteInput
}
},
updater: store => {
const rootCon = ConnectionHandler.getConnection(store.get('client:root'), 'RootNotesConnection_notes');
const payload = store.getRootField('createNote');
const newRootEdge = payload.getLinkedRecord('noteEdge');
const prevRootEdges = rootCon.getLinkedRecords('edges');
const nextRootEdges = [...prevRootEdges, newRootEdge];
rootCon.setLinkedRecords(nextRootEdges, 'edges');
const userCon = ConnectionHandler.getConnection(store.get(userId), 'UserNotesConnection_notes');
const newNote = newRootEdge.getLinkedRecord('node');
const newUserEdge = ConnectionHandler.createEdge(store, userCon, newNote, 'UserNotesEdge');
newUserEdge.setValue(newRootEdge.getValue('cursor'), 'cursor');
const prevUserEdges = userCon.getLinkedRecords('edges');
const nextUserEdges = [...prevUserEdges, newUserEdge];
userCon.setLinkedRecords(nextUserEdges, 'edges');
}
});
setNewNoteInput('');
}
}
Need help passing data "locationpos"= index of my Locations[] from function to class. I'm very new to React and I'm not sure what I'm doing wrong.
ERROR
Failed to compile
./src/components/data.js
Line 20:30: 'locationpos' is not defined no-undef
Search for the keywords to learn more about each error.
This error occurred during the build time and cannot be dismissed.
class Data {
constructor(locationpos) {
this.locationpos=locationpos;
this.updateData();
}
getTimes(date = null) {
date = date === null ? moment().format('DD/MM/YYYY') : date;
var data = this.getData();
return data ? data[date] : [];
}
getSpeadsheetUrl() {
return config.myData[locationpos];
}
function Daily({ locationProps = 1, root }) {
const context = useContext(ThemeContext);
const localization = useCallback(() => {
if (root && cookies.get("location") !== undefined) {
return cookies.get("location");
}
return locationProps;
}, [locationProps, root]);
const [locationState] = useState(localization());
const handleClick = event => {
window.focus();
notification.close(event.target.tag);
};
const openNav = () => {
document.getElementById("sidenav").style.width = "100%";
};
const closeNav = e => {
e.preventDefault();
document.getElementById("sidenav").style.width = "0";
};
// eslint-disable-next-line
const locationpos = locations.indexOf(locations[locationState]);
const _data = useRef(new Data(locationpos));
const getTimes = () => _data.current.getTimes();
Inside your data class, you need to use the instance variable as this.locationPos
getSpeadsheetUrl() {
return config.myData[this.locationpos];
}
I have an API call in api.js:
export const getGraphData = (domain, userId, testId) => {
return axios({
url: `${domain}/api/${c.embedConfig.apiVersion}/member/${userId}/utests/${testId}`,
method: 'get',
});
};
I have a React helper that takes that data and transforms it.
import { getGraphData } from './api';
const dataObj = (domain, userId, testId) => {
const steps = getGraphData(domain, userId, testId)
.then((result) => {
return result.attributes;
});
console.log(steps);
// const steps = test.get('steps');
const expr = /select/;
// build array of steps that we have results in
const resultsSteps = [];
steps.forEach((step) => {
// check for types that contain 'select', and add them to array
if (expr.test(step.get('type'))) {
resultsSteps.push(step);
}
});
const newResultsSteps = [];
resultsSteps.forEach((item, i) => {
const newMapStep = new Map();
const itemDescription = item.get('description');
const itemId = item.get('id');
const itemOptions = item.get('options');
const itemAnswers = item.get('userAnswers');
const newOptArray = [];
itemOptions.forEach((element) => {
const optionsMap = new Map();
let elemName = element.get('value');
if (!element.get('value')) { elemName = element.get('caption'); }
const elemPosition = element.get('position');
const elemCount = element.get('count');
optionsMap.name = elemName;
optionsMap.position = elemPosition;
optionsMap.value = elemCount;
newOptArray.push(optionsMap);
});
newMapStep.chartType = 'horizontalBar';
newMapStep.description = itemDescription;
newMapStep.featured = 'false';
newMapStep.detailUrl = '';
newMapStep.featuredStepIndex = i + 1;
newMapStep.id = itemId;
newMapStep.isValid = 'false';
newMapStep.type = 'results';
const listForNewOptArray = List(newOptArray);
newMapStep.data = listForNewOptArray;
newMapStep.userAnswers = itemAnswers;
newResultsSteps.push(newMapStep);
});
return newResultsSteps;
};
export default dataObj;
The issue is steps, when logged outside the .then() returns a Promise {<pending>}. If I log results.attributes inside the .then(), I see the data fully returned.
You need to wait until your async call is resolved. You can do this by chaining on another then:
getGraphData(domain, userId, testId)
.then((result) => {
return result.attributes;
})
.then(steps => {
// put the rest of your method here
});
You can also look at async/await if your platform supports it which would allow code closer to your original
const steps = await getGraphData(domain, userId, testId)
.then((result) => {
return result.attributes;
});
// can use steps here
You have 2 options to transform your fetched data :
1st option : create a async function that returns a promise with the modified data :
const dataObj = (domain, userId, testId) => {
return getGraphData(domain, userId, testId).then((result) => {
const steps = result.attributes;
const expr = /select/;
// build array of steps that we have results in
const resultsSteps = [];
steps.forEach((step) => {
// check for types that contain 'select', and add them to array
if (expr.test(step.get('type'))) {
resultsSteps.push(step);
}
});
const newResultsSteps = [];
resultsSteps.forEach((item, i) => {
const newMapStep = new Map();
const itemDescription = item.get('description');
const itemId = item.get('id');
const itemOptions = item.get('options');
const itemAnswers = item.get('userAnswers');
const newOptArray = [];
itemOptions.forEach((element) => {
const optionsMap = new Map();
let elemName = element.get('value');
if (!element.get('value')) {
elemName = element.get('caption');
}
const elemPosition = element.get('position');
const elemCount = element.get('count');
optionsMap.name = elemName;
optionsMap.position = elemPosition;
optionsMap.value = elemCount;
newOptArray.push(optionsMap);
});
newMapStep.chartType = 'horizontalBar';
newMapStep.description = itemDescription;
newMapStep.featured = 'false';
newMapStep.detailUrl = '';
newMapStep.featuredStepIndex = i + 1;
newMapStep.id = itemId;
newMapStep.isValid = 'false';
newMapStep.type = 'results';
const listForNewOptArray = List(newOptArray);
newMapStep.data = listForNewOptArray;
newMapStep.userAnswers = itemAnswers;
newResultsSteps.push(newMapStep);
});
return newResultsSteps;
});
};
With es7 async/await syntax it should be :
const dataObj = async (domain, userId, testId) => {
const result = await getGraphData(domain, userId, testId);
const steps = result.attributes;
... modify the data
}
Then keep in mind that this function returns a promise, you'll need to wait for it to get the result, example in a react component :
componentDidMount(){
dataObj('mydomain', 'myuserId', 'mytestId').then((res) => {
this.setState({ data: res });
}
}
The component will update when the promise is resolve, you can then use the data (you'll need to handle the undefined data state in render method)
2nd option : Create a sync function to modify the data :
const dataObj = (steps) => {
const expr = /select/;
const resultsSteps = [];
steps.forEach((step) => {
...
}
return newResultsSteps;
};
To have the same result as option 1 in our component we'll use it like this :
componentDidMount(){
getGraphData('mydomain', 'myuserId', 'mytestId').then((res) => {
const modifiedData = dataObj(res);
this.setState({ data: modifiedData });
}
}
That's how promises work. The data is not ready when you are trying to use it so you should move all your processing into the .then. The reason your variable is a Promise {<pending>} is because you can chain other things onto it.
Something like:
steps.then((steps) => {
...
});
Is it possible to test the code below with Jasmine testing tool or any other npm module like rewire or similar?
const AuthValidatorDumb = require('./src/AuthValidatorDumb');
const AuthValidator = require('./src/AuthValidator');
const config = require('../config');
let instance;
if (!instance) {
if (config.get('auth.enabled')) {
instance = AuthValidator;
} else {
instance = AuthValidatorDumb;
}
}
module.exports = instance;
I've got a variant for testing the code above.Suppose you have:
1) The code for index.js in the question above.
2) AuthValidator.js:
class AuthValidator {}
module.exports = AuthValidator;
3) AuthValidatorDumb.js:
class AuthValidatorDumb {}
module.exports = AuthValidatorDumb;
Here is test/index.spec.js:
const proxyquire = require('proxyquire');
const AuthValidator = require('../src/AuthValidator');
const AuthValidatorDumb = require('../src/AuthValidatorDumb');
describe('auth index', () => {
it('should return AuthValidator', () => {
const configMock = { get: () => 'sth' };
const Instance = proxyquire('../index', {
'../config': configMock,
});
expect(new Instance() instanceof AuthValidator).toBeTruthy();
});
it('should return AuthValidatorDumb', () => {
const configMock = { get: () => undefined };
const Instance = proxyquire('../index', {
'../config': configMock,
});
expect(new Instance() instanceof AuthValidatorDumb).toBeTruthy();
});
});