So I am using Cloud Functions at the moment. What I am doing is this:
export const onMessageCreate = functions.database.ref('/Users/{user}/{message}/{text}').onCreate((snapshot, context) => {
const data = snapshot.val()
const changedData: string = change(byteData.text)
return snapshot.ref.update({id: compressedByteData}) //This is the problem
})
The change(input: string): string is a custom function of mine that just replaces every occurrence of the word happy birthday with a birthday cake emoji. Thing is however that in my reference which looks like this: "/Users/{user}/master/{messageGroup}/content/{message}" I want to update the value of text. Since, however, I don't know what {text} is I can't store it in the correct location. Does anyone have some suggestions?
The change() function is:
function change(data:string):string {
return data.replace(/\bhappy-birthday\b/g, '🎂')
}
Here is the Firebase node picture:
Firebase Node Setup
So I want to change the 01, 02, 03 with my Cloud Functions (the values don't matter).
Visual Representation of what I want to do:
Visual Representation
New Update following your comments:
If I understand correctly your last comments, this should do the trick:
export const onMessageCreate = functions.database.ref('/Users/{user}/master/{messageGroup}/content/{message}').onCreate((snapshot, context) => {
const data = snapshot.val();
const changedData: string = change(byteData.text);
const user = context.params.user;
const messageGroup = context.params.messageGroup;
return admin.database().ref(`/Users/${user}/master/${messageGroup}/content`).update({4f3f: changedData});
})
Update following your comments:
Sorry but it not 100% clear what you want to update.
If you want "change the value of /Users/{user}/master/{messageGroup}/content/{message} when (you) create the value at /Users/{user}/master/{messageGroup}/content/{message}" with the value of changedData, just do as follows:
export const onMessageCreate = functions.database.ref('/Users/{user}/master/{messageGroup}/content/{message}').onCreate((snapshot, context) => {
const data = snapshot.val();
const changedData: string = change(byteData.text);
return snapshot.ref.update({message: changedData});
})
Within your Cloud Function you will be able to get the path values by doing
const user = context.params.user;
const message = context.params.message;
and then build the desired node reference.
As you can read in the documentation:
You can specify a path component as a wildcard by surrounding it with curly brackets; ref('foo/{bar}') matches any child of /foo. The
values of these wildcard path components are available within the
EventContext.params object of your function. In this example, the
value is available as event.params.bar.
Related
I'm working with the outputs of an Intranet I don't control.
I have this string:
let template = 'LAWYER=|FIRM=|SUIT_DESCRIPTION=|DEF_COMMENT=|PLF_COMMENT=|';
It goes on longer, but that's the pattern.
Now there's another similar string, but with data assigned, as in this example:
let current= 'FIRM=Smith and Wesson LLP|SUIT_DESCRIPTION=It\'s a royal mess|PLF_COMMENT=some freeform text|LAWYER=Bob Smith';
Now, notice that not every element in template is necessarily represented in current, and the order may be different (if the latter fact is a big deal, I can ensure the order is the same).
What I'm trying to do, is take every element that is in current, and populate the matching element in template, if it exists. (or, alternatively and potentially preferred, insert every non-matching element in template into current, but ideally in the same order as template).
Using the date above, the result I'm looking for is:
result = 'LAWYER=Bob Smith|FIRM=Smith and Wesson LLP|SUIT_DESCRIPTION=It\'s a royal mess|DEF_COMMENT=|PLF_COMMENT=some freeform text|';
I'm not very accomplished with JavaScript :(
I tried various things in JSFiddle using split() and match() but I just made a mess of it.
// Convert the template to an array of keys
const getKeys = str => str.split('|').map(entry => entry.split('=')[0]);
// Convert the data to an object
const toObj = str => Object.fromEntries(str.split('|').map(entry => entry.split('=')));
// Reconcile the data with the template
const compile = (templateStr, dataStr) => {
const keys = getKeys(templateStr);
const data = toObj(dataStr);
return keys.reduce((results, key) => {
if(key) results.push([key, data[key] ?? '']);
return results;
}, []);
};
// Convert the results back into a string
const toString = data => data.map(entry => entry.join('=')).join('|') + '|';
// And then a test
let template = 'LAWYER=|FIRM=|SUIT_DESCRIPTION=|DEF_COMMENT=|PLF_COMMENT=|';
let current = 'FIRM=Smith and Wesson LLP|SUIT_DESCRIPTION=It\'s a royal mess|PLF_COMMENT=some freeform text|LAWYER=Bob Smith';
console.log(toString(compile(template, current)));
I want to add another object to my exiting object but i doesn't get the value as others object have instead it gets a text, I tried a easy solution but didn't work, here is that i'm facing:
ConsoleLog Image
So instead of the key long I want to keep the numbers as they started from 0, but I don't know how?
Here is what I've tried:
const addToWatchlist = (movie) => {
const long = movies.length;
const data = {...movies, long: movie};
setMovies(movies)
ps: I'm using React.
const addToWatchlist = (movie) => {
movies.push(movie)
setMovies(movies)
The issue I am having is displayed in the picture.
I am able to convert the strings into number type using map but when wishing to push to an array of numbers I am unable to. Also I am trying to maintain types but I believe this may be the issue but I am unable to make headway.Maybe I should create another variable and store the newly created number values into that array? Also when console logging I am just getting the single value as a number and not as an array.
openValues: string | number[];
I hope someone can please help...
getData() {
this.pricingService.getDailyPricing().subscribe((data) => {
this.dailyData = data;
const timeSeries = data['Time Series (Daily)'];
const dailyDates = Object.keys(timeSeries);
dailyDates.forEach((parentKey) => {
const parentValue = timeSeries[parentKey];
const childKeys = Object.keys(parentValue);
this.dailyDates = new Date(parentKey);
childKeys.forEach((childKey) => {
const keyName = childKey;
const keyValue = parentValue[childKey];
this.timeSeriesSeperationMethod(keyName, keyValue);
});
});
});
}```
The image attached contains the issue.
[![The Image of this issue able to convert to number but unable to push to an array of numbers][1]][1]
[1]: https://i.stack.imgur.com/pL1JA.gif
I have a method called populateProvidedValuesForNewMandate that looks like this
exports.populateProvidedValuesForNewMandate = (team, assignee, disputeValue, lawField,
subjectOfDispute, party, fileReference, costUnit, clientUnit, sideEffect, comment) => {
const teamInput = element(by.css('div#team input'));
const assigneeInput = element(by.css('div#assignee input'));
const disputeValueInput = element(by.id('dispute_value'));
const lawFieldInput = element(by.css('div#law_field input'));
const subjectOfDisputeInput = element(by.id('subject_of_dispute'));
const partyInput = element(by.id('party'));
const fileReferenceInput = element(by.id('file_reference'));
const costUnitInput = element(by.css('div#cost_unit input'));
const clientUnitInput = element(by.id('client_unit'));
const sideEffectInput = element(by.css('div#side_effect input'));
const mandateComment = element(by.id('mandate_comment'));
// TODO: Figure out how to choose these dynamically as well
// relevantCase, risReportRelevant, economicRelevance, activePassive
const relevantCaseInput = element(by.css(".relevant_case input[value='no']"));
const riskReportRelevantInput = element(by.css(".risk_report_relevant input[value='no']"));
const economicRelevanceInput = element(by.css("label[for='economic_relevance']"));
const activePassiveInput = element(by.css(".active_passive input[value='passive']"));
teamInput.sendKeys(team);
assigneeInput.sendKeys(assignee);
disputeValueInput.sendKeys(disputeValue);
lawFieldInput.sendKeys(lawField);
subjectOfDisputeInput.sendKeys(subjectOfDispute);
partyInput.sendKeys(party);
fileReferenceInput.sendKeys(fileReference);
costUnitInput.sendKeys(costUnit);
clientUnitInput.sendKeys(clientUnit);
sideEffectInput.sendKeys(sideEffect);
mandateComment.sendKeys(comment);
// TODO: Figure out how to choose these dynamically as well
// relevantCase, risReportRelevant, economicRelevance, activePassive
browser.actions().mouseMove(relevantCaseInput).doubleClick().perform();
browser.actions().mouseMove(riskReportRelevantInput).click().perform();
browser.actions().mouseMove(economicRelevanceInput).click().perform();
browser.actions().mouseMove(activePassiveInput).click().perform();
};
and here is an example of its use case
values.populateProvidedValuesForNewMandate(texts.DISPUTE_VALUE, texts.PARTY, texts.CLIENT_UNIT,
texts.SIDE_EFFECT, texts.COMMENT);
The method fills out the specified values that lie within a file called texts.js into the appropriate fields. The problem is that I get the error message: 'each key must be a number of string; got undefined' meaning that this method doesn't work because I have to send the keys for each specified variable in the method.
I really want to avoid sending empty strings for this method (especially because it won't work, I've tried it out -> I get a error from the app itself, not protractor/selenium).
How can I turn this method into one that only considers the specified variables in the test cases.
Also as you can see from my comment, I am trying to figure out how to do this for the checkbox and radio buttons as well. If anyone has a hint, I'd really appreciate it
Honestly, only you can answer the question. Because there are hundreds of ways to fo this, and some may work better than another. So to us it's silly to make guesses which way is the best for you. So I'll give one example and hopefully you can take it from here
One way is to make the method accept an object and check if a property has been passed
function fillForm(obj) {
if (obj.hasOwnProperty('team')) teamInput.sendKeys(team);
if (obj.hasOwnProperty('assignee')) assigneeInput.sendKeys(assignee);
if (obj.hasOwnProperty('disputeValue')) disputeValueInput.sendKeys(disputeValue);
// ...
}
and then call it
fillForm({
assignee: texts.ASIGNEE,
disputeValue: texts.DISPUTE_VALUE
})
so it will skip sending keys to team field
In my ReactJS application I am getting the mobile numbers as a string which I need to break and generate a link for them to be clickable on the mobile devices. But, instead I am getting [object Object], [object Object] as an output, whereas it should be xxxxx, xxxxx, ....
Also, I need to move this mobileNumbers function to a separate location where it can be accessed via multiple components.
For example: Currently this code is located in the Footer component and this code is also need on the Contact Us component.
...
function isEmpty(value) {
return ((value === undefined) || (value === null))
? ''
: value;
};
function mobileNumbers(value) {
const returning = [];
if(isEmpty(value))
{
var data = value.split(',');
data.map((number, index) => {
var trimed = number.trim();
returning.push(<NavLink to={`tel:${trimed}`} key={index}>{trimed}</NavLink>);
});
return returning.join(', ');
}
return '';
};
...
What am I doing wrong here?
Is there any way to create a separate file for the common constants / functions like this to be accessed when needed?
First question:
What am I doing wrong here?
The issue what you have is happening because of Array.prototype.join(). If creates a string at the end of the day. From the documentation:
The join() method creates and returns a new string by concatenating all of the elements in an array (or an array-like object), separated by commas or a specified separator string. If the array has only one item, then that item will be returned without using the separator.
Think about the following:
const navLinks = [{link:'randomlink'}, {link:'randomlink2'}];
console.log(navLinks.join(','))
If you would like to use concatenate with , then you can do similarly like this:
function mobileNumbers(value) {
if(isEmpty(value)) {
const data = value.split(',');
return data.map((number, index) => {
const trimed = number.trim();
return <NavLink to={`tel:${trimed}`} key={index}>{trimed}</NavLink>;
}).reduce((prev, curr) => [prev, ', ', curr]);
}
return [];
};
Then you need to use map() in JSX to make it work.
Second question:
Is there any way to create a separate file for the common constants / functions like this to be accessed when needed?
Usually what I do for constants is that I create in the src folder a file called Consts.js and put there as the following:
export default {
AppLogo: 'assets/logo_large.jpg',
AppTitle: 'Some app name',
RunFunction: function() { console.log(`I'm running`) }
}
Then simply import in a component when something is needed like:
import Consts from './Consts';
And using in render for example:
return <>
<h1>{Consts.AppTitle}</h1>
</>
Similarly you can call functions as well.
+1 suggestion:
Array.prototype.map() returns an array so you don't need to create one as you did earlier. From the documentation:
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
I hope this helps!