Javascript initializing properties - javascript

I have a small discussion with my colleague and I would like to know what other people think about this. I don't like initializing properties that might not be used.
The regex is not in the method itself because we don't want to initialize the regex every time.
File helpers/service.js
How I would do it:
let serviceCheckRegExp = null;
export const isServiceUrl = url => {
if (!serviceCheckRegExp) serviceCheckRegExp = new RegExp(getApi('service'),'i');
return serviceCheckRegExp.test(url);
};
How my colleague would do it:
const serviceCheckRegExp = new RegExp(getApi('service'),'i');
export const isServiceUrl = url => serviceCheckRegExp.test(url);

Related

How to reuse MotorCortex incidents

I have a clip that I develop and I want to reuse a fade in incident instead o creating a new incident every time is this possible? The way I am doing it at the moment looks like this:\
const attrs = {animatedAttrs:{opacity:1}}
const props = {selector:".elem",duration:1000}
const fadeInOne = new CSSEffect(attrs,props)
const fadeInTwo = new CSSEffect(attrs,props)
clip.addIncindet(fadeOne,1000)
// do something else and then later on
clip.addIncident(fadeTwo,1000)
Is there a better way to do this?
To accomplish what you want you could do the following:
const attrs = {animatedAttrs:{opacity:1}}
const props = {selector:".elem",duration:1000}
const fadeIn = () => new CSSEffect(attrs,props)
clip.addIncindet(fadeIn(),1000)
// do something else and then later on
clip.addIncident(fadeIn(),1000)
Note *: you could add argument to the fadeIn function and make some of the data dynamic such as the selector or the duration, or event add different easing.

Websockets in Sapper

I have a readable store in Svelte that looks like this:
const state = {};
export const channels = readable(state, set => {
let st = state;
let socket = new WebSocket("ws://127.0.0.1:5999");
socket.onmessage = function (event) {
var datastr = event.data.split(':');
st[datastr[0]].value = datastr[1];
st[datastr[0]].timestamp = Date.now();
set(st)
};
return () => {
socket.close()
}
});
When I import it to my Svelte App works. But if I put that App.svelte as my index.svelte running on Sapper, it doesnt work at first. It says error 500 websocket is not defined. Once I reload the page in the browser start to work...
I have try to parse a function that creates the store instead:
export const getChannel = () => {
// here my store
return {...store}
}
and then creating the store inside a onMount() like this:
onMount( ()=> {
const channel = getChannel();
});
But doesnt seem to do the trick... What do I miss?
Note: If a just replace the store by a simple writable, and create the websocket onMount(), it works without any problem. I just only wanted to put all the communication inside the store as a readable...
In Sapper, code in components (or imported into components) is executed in Node during server-side rendering unless it's put inside onMount (which doesn't run on the server, because there's no 'mounting' happening) or an if (process.browser) {...} block, or something equivalent.
That includes things like references to $channels causing channels.subscribe(...) to be called during initialisation.
Since there's no WebSocket global in Node, creating that subscription will fail. The simplest workaround is probably a simple feature check:
const state = {};
export const channels = readable(state, (set) => {
if (typeof WebSocket === 'undefined') return;
let st = state;
let socket = new WebSocket("ws://127.0.0.1:5999");
socket.onmessage = function (event) {
var datastr = event.data.split(":");
st[datastr[0]].value = datastr[1];
st[datastr[0]].timestamp = Date.now();
set(st);
};
return () => {
socket.close();
};
});

JavaScript send out an alert to prompt and edit array?

//global variable
var memArray =[];
//object
function member(id, password){
this.id = id;
this.pwd = password
}
var memObj1=new member("m001","123");
memArray.push(memObj1);
How do I send out an alert to prompt and edit each object that is push to memArray?
if you want to customize it try to use your own modals instead of window.prompt and just display values with editable text fields, on submit capture those values and change them in array respectively.
var memArray = [];
//object
function member(id, password) {
this.id = id;
this.pwd = password
}
var memObj1 = new member("m001", "123");
var memObj2 = new member("m002", "123");
var memObj3 = new member("m031", "123");
memArray.push(memObj1);
memArray.push(memObj2);
memArray.push(memObj3);
memArray.forEach((val, ind) => {
memArray[ind] = JSON.parse(window.prompt("want to edit values?", JSON.stringify(memArray[ind])));
});
console.log(memArray)
Pavan's answer is good, but to make this testable in automated tests:
// I would name these fields in your API
// by making the constructor take an object.
// Capitalise the name to signal that it can be newed
function Member({id, password}) {
this.id = id;
this.pwd = password
}
// Name the array for what it is
const members = [
new Member({id: "m001", password: "123"}),
new Member({id: "m002", password: "123"}),
new Member({id: "m031", password: "123"})
]
const editInBrowserFn = member => JSON.parse(window.prompt("want to edit values?", JSON.stringify(member)));
const updateMembers = editFn => array => array.map(editFn)
// To get an update
const updatedMembers = updateMembers(editInBrowserFn)(members)
console.log(updatedMembers)
// You can now test it by making an testing editFn that doesn't need user interaction
const testEditFn = m => new Member({id: m.id, password: 'test'})
const testMembers = updateMembers(testEditFn)(members)
console.log(testMembers)
See this article for an in-depth explanation of this approach.
To do it this way, you will need to take it out of the global scope. That is a good discipline to develop. As a first step you could make an object in global scope that holds the latest member list:
const Members = (() => {
let _members = []
return {
setMembers: members => _members = [...members],
getMembers: () => [..._members]
}
})()
Now the way to update the members is like this:
const updateFn = updateMembers(editInBrowser)
function updatePasswords() {
const members = Members.getMembers()
Members.setMembers(updateFn(members))
}
Nothing can accidentally delete or mutate the members array now, so that bug surface area is eliminated.
This is how React setState is designed. It's inspired by functional programming ideas and immutability.
You probably want to be able to update just one member, so:
const Members = (() => {
let _members = []
return {
setMembers: members => _members = [...members],
getMembers: () => [..._members],
updateMember: updated =>
this.members = _members.map(m =>
m.id === updated.id ? updated : m)
}
})()
Now all your array mutation is in one single place, and you only have to make it bug-free there. Otherwise, your global state is exposed and you have to fix bugs everywhere related to it. Without this, all your calling functions are responsibly for correctly managing the global state of the application. Complex.
Crystallise the complexity in one place.
I wrote an article and a complete implementation of the store (in 40 lines of code) here.
As far as I concern, alerts are just models on the browser to provide informative feedback to a particular user on his actions. Therefore, I think it is required to use either a dialog model or a form to edit the objects in the memArray.

TypeError: Attempted to wrap getRepository which is already wrapped

I need to wrap a method multiple time with sinon to be able to return different objects based on the argument. How would I do this?
The controller I want to test looks something like this:
const servicePackagesOfferingRepository = Salesforce.getRepository(ServicePackageOffering);
const servicePackageOffering = await servicePackagesOfferingRepository.findOneById(model.servicePackageOfferingId);
const serviceCallRepository = Salesforce.getRepository(ServiceCall);
serviceCall = await serviceCallRepository.save(serviceCall);
And the unit test something like this:
const servicePackagesOfferingRepository = new Repository(ServicePackageOffering);
const servicePackagesOfferingRepositoryMock = sandbox.mock(servicePackagesOfferingRepository);
servicePackagesOfferingRepositoryMock
.expects('findOneById')
.withArgs(inputModel.servicePackageOfferingId)
.resolves({});
sandbox
.mock(Salesforce)
.expects('getRepository')
.withArgs(ServicePackageOffering)
.returns(servicePackagesOfferingRepository);
const serviceCallRepository = new Repository(ServiceCall);
const serviceCallRepositoryMock = sandbox.mock(serviceCallRepository);
serviceCallRepositoryMock
.expects('save')
.once();
sandbox
.mock(Salesforce)
.expects('getRepository')
.withExactArgs(ServiceCall)
.returns(serviceCallRepository);
But I get this error:
TypeError: Attempted to wrap getRepository which is already wrapped
Found a way to do it:
const SalesforceMock = sandbox.mock(Salesforce);
SalesforceMock.expects('getRepository')
.twice()
.onFirstCall()
.returns(serviceCallRepository)
.onSecondCall()
.returns(clientRepository);

How to compare old and new value with Cloud Functions for Firebase with .onWrite or onchange?

Lets take the following data structure:
Now I want to refresh the accessTokenFacebook with a Firebase Function.
I tested two option:
the onWrite, and the:
the onChanged
The onWrite looks the best to me, but with the following function:
exports.getFacebookAccessTokenOnchange = functions.database.ref('/users/{uid}/userAccountInfo/lastLogin').onWrite(event => {
const lastLogin = event.data;
let dateObject = new Date();
let currentDate = dateObject.toUTCString();
return lastLogin.ref.parent.parent.child('services').child('facebook').update({'accessTokenFacebook': currentDate});
});
Something happens I don'understand/can solve: when I delete a whole userUID-record (for a cleanup), the userUID-record automatically create, then only with the following path {uid}/services/facebood/accesTokenFacebook...
It seems that a deletion also triggers a onWrite.
I also tried the .onchange, but that one only triggers when there is still no accessTokenFacebook. When the change make this one, the change never triggered again.
So the next thing I want to do is a comparison between the old and new value. Do you have an example? Or is there a better solution?
UPDATE:
Cloud Functions recently introduced changes to the API as noted here.
Now (>= v1.0.0)
exports.dbWrite = functions.database.ref('/path').onWrite((change, context) => {
const beforeData = change.before.val(); // data before the write
const afterData = change.after.val(); // data after the write
});
Before (<= v0.9.1)
exports.dbWrite = functions.database.ref('/path').onWrite((event) => {
const beforeData = event.data.previous.val(); // data before the write
const afterData = event.data.val(); // data after the write
});
Now that these functions are deprecated and this is the number one search result for this subject, here is the new updated version that Cloud Functions now use.
exports.yourFunction = functions.database.ref('/path/{randomPath}/goes/here').onWrite((change, context) => {
// Your value after the write
const newVal = change.after.val();
// Your value before the write
const oldVal = change.before.val();
});

Categories

Resources