Hello I have a method where I have to print address in this format:-
AddressLine1,
City, State
In other words I want a line break after AddressLine1.
So I have a method like this:-
const getAddress = pursuit => {
if(pursuit.address!=null){
const addressLine1 = pursuit.address.addressLine1;
const cityState = `${pursuit.address.addressCity}, ${pursuit.address.addressState.value}`;
return `${addressLine1},\n
${cityState}`;
}
return '';
};
But it doesn't give me the desired result.
You are having issues because you are already inserting a line break and leading whitespace in your template string. To achieve your desired result, you can just have the \n, that is, everything on a single line:
const getAddress = pursuit => {
if(pursuit.address!=null){
const addressLine1 = pursuit.address.addressLine1;
const cityState = `${pursuit.address.addressCity}, ${pursuit.address.addressState.value}`;
return `${addressLine1},\n${cityState}`;
}
return '';
};
A shorter and runnable example:
const part1 = 'A long text that'
const part2 = 'continues below';
const longText = `${part1}\n${part2}`;
console.log(longText);
Related
I've written a content scraper code with library Cheerio.js, it read the content of a webpage and grabs me some values like location name, street address, and phone no.
In some places, the street address isn't provided so it skips that place which isn't cool.
Here is an example of the webpage that I'm getting the data from.
https://www.yellowpages.com/search?search_terms=Medical%20Ambulance&geo_location_terms=Los%20Angeles%2C%20CA&page=2
How do I detect if the street address isn't located here & my code should replace the empty content with something else?
Full code is located here.
https://github.com/jpca999/yellowpageScrapper/blob/master/indexWithAsyncArray.js
Currently, in the output, it just skips the empty street names.
const getStreetAddress = async () => {
console.log(' calling getStreetAddress');
const html = await rp(baseURL + searchURL);
const businessMap = cheerio('div.street-address', html).map(async (i, e) => {
const streetAddress = e.children[0].parent.children[0].data;
console.log('Here it shold detect if the variable "streetAddress" has some value then leave it or else replace the value with something' );
return {
streetAddress,
}
})
.get();
return Promise.all(businessMap);
};
Here's the output.
If this were mine, and unfortunately I have no way to test this myself with your entire code base, I would just check the value against a default value. The basic paradigm I've used in JavaScript, which some people like and some don't, and you can adapt to your own taste, is
const actualValue = possibleValue || defaultValue;
So in your case it might be
const streetAddress = e.children[0].parent.children[0].data || 'No Street Address Provided';
This is because null, undefined, and empty string are all falsey value and such will cause the default value to be assigned.
You can do the same thing after your object is returned, for example
const businessMap = ... blah ... .get();
businessMap.streetAddress = businessMap.streetAddress || 'No Street Address Provided';
return Promise.all(businessMap);
That page doesn't load for me, but it should look something like (assuming the css for streetAddress is .foo)
const $ = cheerio.load(html)
const businessMap = $('div.street-address').get().map(div => {
return {
streetAddress: $(div).find('.foo').first().text() || "???"
}
})
Also note that cheerio doesn't use promises because there's no IO.
Also note that the empty string "" is falsey in JS which is why this works.
I am trying to insert array in my firebase collection from cloud function. I need to have multiple lines in one document so for each line i am inserting an array. Please check my attached screenshot where you can see line0 , same way i need to have Line1,Line2,Line3..,Line n in the same document.
for line0 i am passing array from code like below and its working fine.
admin.firestore().collection("qbContestWinners").add(
{
'cmpientryid': context.params.processId,
'qbid': '',
'qbsyncdate': '',
'qbsyncstatus': 'pending',
'Line0':
{
id: "0",
description: 'PRIZE AMOUNT',
amount: 1000,
accountrefid: contestresultData.qbcontestid,
accountrefname: contestresultData.qbcontestname,
contestresultId: context.params.processId,
},
})
when i am looping through data i am getting from another table , i am not able to generate proper JSON to insert.
below is how i am looping and creating JSON after getting data from another table.
i = 1;
admin.firestore().collection("results").where('cid', '==', 'LKRRk2XXXXXXXX')
.orderBy("rank", "asc").get().then(snapshots =>
{
snapshots.forEach(doc =>
{
const contestresultId = doc.id;
const prizeAmount = doc.data().prizeamt;
const userId = doc.data().userid;
const lineNum = "Line" + i;
console.log("new line numner is: ", lineNum);
console.log(`lineNum? ${lineNum}`);
const linetxt = "Line" + String(i);
const insertData = "{"+linetxt +
":{id:'" + i +
"', description: 'PRIZE AMOUNT'"+
", amount:" + prizeAmount + "," +
"accountrefid:"+ contestresultData.qbcontestid +","+
"accountrefname:'" +contestresultData.qbcontestname +"',"+
"contestresultId:'" + contestresultId +"'," +
"},}"
const finalInsert = JSON.stringify(insertData);
const finalJSON = JSON.parse(finalInsert);
admin.firestore().collection("qbContestWinners").doc(mainID).set(
finalInsert.toJSON(),
{
merge: true
});
i= i+1;
});
});
using this code i am getting error
finalInsert.toJSON is not a function
Actually, the Line0 field is a map and not an Array, see this doc for more details.
So, if you want to create similar fields (Line1, Line2, ...), you simply need to pass a JavaScript Object to the set() method, as follows:
snapshots.forEach(doc => {
const contestresultId = doc.id;
const prizeAmount = doc.data().prizeamt;
const userId = doc.data().userid;
const lineNum = "Line" + i;
console.log("new line numner is: ", lineNum);
console.log(`lineNum? ${lineNum}`);
const lineObj = {
id: i,
description: 'PRIZE AMOUNT',
accountrefid: contestresultData.qbcontestid, //Not sure if you have defined contestresultData somewhere...
//...
}
const dataObj = {};
dataObj["Line" + i] = lineObj // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors
admin.firestore().collection("qbContestWinners").doc(mainID).set(dataObj, {merge: true});
i= i+1;
});
HOWEVER, note that you must return a promise that resolves when all the asynchronous work in your Cloud Function is complete (i.e. call to the Firestore set() method).
This is explained in the official Firebase video series, watch in particular the three videos titled "Learn JavaScript Promises".
Since you are calling several times the set() method in a forEach loop, you need to use Promise.all() in order to return a Promise when all these parallel calls to the set() method are completed.
The following should do the trick:
let i = 1;
return admin.firestore().collection("results") // <-- See the return here
.where('cid', '==', 'LKRRk2XXXXXXXX')
.orderBy("rank", "asc").get()
.then(snapshots => {
const promises = [];
snapshots.forEach(doc => {
const contestresultId = doc.id;
const prizeAmount = doc.data().prizeamt;
const userId = doc.data().userid;
const lineNum = "Line" + i;
const lineObj = {
id: i,
description: 'PRIZE AMOUNT',
accountrefid: contestresultData.qbcontestid,
//...
}
const dataObj = {};
dataObj[lineNum] = lineObj;
promises.push(admin.firestore().collection("qbContestWinners").doc(mainID).set(dataObj, {merge: true}));
i= i+1;
});
return Promise.all(promises) // <-- See the return here
});
A last remark: if mainID keeps the same value in the snapshots.forEach loop, you may adopt a totally different approach, consisting in building a JavaScript object with several LineXX properties and call the set() method only once. Since you didn't share the entire code of your Cloud Function it is impossible to say if this approach should be used or not.
first to the error
You stringify and parse a string. The problem here seems to be the order. You have to parse a "String" and to stringify an "Object". The result won't have a toJSON Method as well, but u can just stringify the Object to get a json.
the second thing
Why do you use a string to create your object? You shouldn't. Just use an object.
the third thing
You should not use Objects as Arrays. Not even in firebase.
Just use arrays. Example:
[Line0Object, Line1Object, ...]
Hint: If your array can work as its own collection. Just use a SubCollection. This might fit your needs.
What I'm looking for is a is something like the underscore on line 5:
const returnValues = () => {
const foo = {'one': 1}
const bar = {'two': 2}
return {
foo, bar
}
}
const { _, valueToBeUsed } = returnValues();
//do things with valueToBeUsed
It'd be nice and clean to have a way to signify that I don't need the first variable.
Some pattern-matching languages like Swift and Haskell call this a wildcard pattern.
Your returnValues function contains invalid syntax. If you meant to use array destructuring here, you can treat the array as an Object instead:
const returnValues = () => {
return [ 1, 2 ];
}
const { 1: valueToBeUsed } = returnValues();
console.log(valueToBeUsed); // 2
If returnValues should return an object, you do not need to destructure unused properties at all:
const returnValues = () => {
return { one: 1, two: 2 };
}
const { two: valueToBeUsed } = returnValues();
console.log(valueToBeUsed); // 2
i'm new to es6 and i have an array of objects like below:
checkProps = [ {symbol: rwerwe}, {side: Buy}, {status: Hey} ]
With a for loop i want to create a string like:
myurl = localhost:3000/symbol=rwerwe&side=Buy&status=Hey
For this i have to get access to the keys of each object and use concat for the string composition. I used Object.keys but it returns integers. I want something to return the symbol, side and status. How to do this?
Please try this:
var checkProps = [ {symbol: 'rwerwe'}, {side: 'Buy'}, {status: 'Hey'} ];
var urlStr = 'localhost:3000/';
var urlParams = [];
checkProps.forEach(function(o) {
var keys = Object.keys(o);
keys.map(function(key) {
urlParams.push(key + '=' + o[key])
});
});
urlStr += urlParams.join('&');
console.log(urlStr)
You need to loop over the array and apply Object.keys to the items.
const parameters = checkProps.map(item => Object.keys(item).map(key => key + "=" + item[key])[0])
.join("&");
const myUrl = `localhost:3000/${parameters}`;
It's a bit cleaner with ES2017 and Object.entries:
const parameters = checkProps.map(item => Object.entries(item)[0])
.map(parameter => parameter.join("="))
.join("&");
I have a text file. I need to read the file inside a function and return it as a JSON object. The following is throwing an error "Unexpected token V in JSON at position 0" .
Server.js
fs.readfile('result.txt', 'utf8', function(err,data) {
if(err) throw err;
obj = JSON.parse(data);
console.log(obj);
});
result.txt looks like the following
VO1: 10 5 2
VO2: 5 3 2
I think I cannot use JSON.parse directly. How do I proceed?
Assuming the following:
Every line is separated by a newline character (\n)
Every line is separated by a : where the part in front of it is the key and the part behind it is a (space) separated string that should indicate the keys values as an array.
Below should work for your format:
fs.readfile('result.txt', 'utf8', function(err,data) {
if(err) throw err;
let obj = {};
let splitted = data.toString().split("\n");
for (let i = 0; i<splitted.length; i++) {
let splitLine = splitted[i].split(":");
obj[splitLine[0]] = splitLine[1].trim();
}
console.log(obj);
});
It could be issue with UTF-8 string format, Tried below code and it works
const resultBuffer = fs.readFileSync('result.txt');
const resultData = JSON.parse(resultBuffer.toString().trim());
Thanks to Baao for providing that answer.
As another flavor of solution, if you don't have any ":" for perhaps a list of files you could always code in a key like so:
var data = fs.readFileSync(pathAndFilename);
var testData = {};
var splitList = data.toString().split('\r\n');
for (var i = 0; i < splitList.length; i++) {
testData['fileNumber' + i.toString()] = splitList[i];
}
You need to parse the text file by yourself. You can use RegExp or some other means to extract the values, create an object out of that and then JSON.stringify it.
improving upon #baao answer:
const fs = require("fs")
fs.readFile('.czrc', 'utf8', function (err, data) {
if (err) {
console.error(err)
throw "unable to read .czrc file.";
}
const obj = JSON.parse(data)
});
Your result.txt is not valid json.
Valid json would look like this.
{
"VO1": [10, 5, 2],
"VO2": [5, 3, 2]
}