Peg.js distinguish between missing values and white space - javascript

I have the following peg.js script:
start = name*
name = '** name ' var ws 'var:' vr:var ws 'len:' n:num? ws 'label:' lb:label? 'type:' ws t:type? '**\n'
{return {NAME: vr,
LENGTH: n,
LABEL:lb,
TYPE: t
}}
type = 'CHAR'/'NUM'
var = $([a-zA-Z_][a-zA-Z0-9_]*)
label = p:labChar* { return p.join('')}
labChar = [^'"<>|\*\/]
ws = [\\t\\r ]
num = n:[0-9]+ {return n.join('')}
to parse:
** name a1 var:a1 len:9 label:The is the label for a1 type:NUM **
** name a2 var:a2 len: label:The is the label for a2 type:CHAR **
** name a3 var:a3 len:67 label: type: **
and I'm encountering a couple of issues.
Firstly, within the text that I am parsing I expect certain value labels such as 'var:', 'len:', 'label:' & 'type:'. I would like to use these labels, as I know they're fixed, to delineate between the values.
Secondly, I need to allow for missing values.
Am I going about this the correct way? Currently my script merges the value of the label with the type and then I get an error at :
Line 1, column 64: Expected "type:" or [^'"<>|*/] but "*" found.
Also, Can I do this with blocks of text too? I tried parsing :
** name a1 var:a1 len:9 label:The is the label for a1 type:NUM **
** name a2 var:a2 len: label:The is the label for a2 type:CHAR **
randomly created text ()= that I would like to keep
** name b1 var:b1 len:9 label:This is the label for b1 type:NUM **
** name b2 var:b2 len: label:This is the label for b2 type:CHAR **
more text
by amending the first line an adding the following:
start = (name/random)*
random = r:.+ (!'** name')
{return {RANDOM: r.join('')}}
I'm after a final result of:
[
[{
"NAME": "a1",
"LENGTH": "9",
"LABEL": "The is the label for a1",
"TYPE": "NUM"
},
{
"NAME": "a2",
"LENGTH": null,
"LABEL": "The is the label for a2",
"TYPE": "CHAR"
},
{"RANDOM":"randomly created text ()= that I would like to keep"}]
[{
"NAME": "b1",
"LENGTH": "9",
"LABEL": "This is the label for b1",
"TYPE": "NUM"
},
{
"NAME": "b2",
"LENGTH": null,
"LABEL": "This is the label for b2",
"TYPE": "CHAR"
},
{"RANDOM":"more text "}]
]

You'll want a negative lookahead !(ws 'type:') otherwise, the label rule will be too greedy and consume all the input to the end of the line.
As a side note, you can use the $() syntax to join the text of elements instead of {return n.join('')}.
start = name*
name = '** name ' var ws 'var:' vr:var ws 'len:' n:num? ws 'label:' lb:label? ws 'type:' t:type? ws '**' '\n'?
{return {NAME: vr,
LENGTH: n,
LABEL:lb,
TYPE: t
}}
var = $([a-zA-Z_][a-zA-Z0-9_]*)
num = $([0-9]+)
label = $((!(ws 'type:') [^'"<>|\*\/])*)
type = 'CHAR'/'NUM'
ws = [\\t\\r ]
Output:
[
{
"NAME": "a1",
"LENGTH": "9",
"LABEL": "The is the label for a1",
"TYPE": "NUM"
},
{
"NAME": "a2",
"LENGTH": null,
"LABEL": "The is the label for a2",
"TYPE": "CHAR"
},
{
"NAME": "a3",
"LENGTH": "67",
"LABEL": "",
"TYPE": null
}
]

Finally got the following to work:
random = r: $(!('** name').)+ {return {"RANDOM": r}}
I'm not sure I completely understand the syntax, but it works.

Related

How to get the filtered object into the json-server when an end user does a rough search?

I am using json-server as my fake API data. I am implementing the search functionality to it. I created an endpoint like this -
getData : ( searchTerm : string ) => axios.get(`http://localhost:3000/books?=${searchTerm}`).then((response) => setData(response));
and I am utilizing into my input field to get the searched results.
Let's say My json object coming back from the Json-server is as follows -
[
{
"Id": 1,
"name" : "car"
},
{
"Id": 2,
"name" : "bike"
},
{
"Id": 3,
"name" : "ninja bike"
}]
now, the problem is , when I search for "car", it gives me the json result.
but, when I search for "brand new car", it should give me the "car's" object at least, as word "car" is a match. but it is giving me [], empty array.
So please suggest me how could i look for specific words into my json-server's data?
so that whenever , the end user even make a vague unstructured search, it should look for specific words like "car", in this case and return that car object.
You can make a simple filter to check if your string is in there
let json = [{
"Id": 1,
"name": "car"
},
{
"Id": 2,
"name": "bike"
},
{
"Id": 3,
"name": "ninja bike"
}
]
let searchString = "brand new car".split(" ") // ["brand", "new", "car"]
let filter = json.filter(json => searchString.includes(json.name))
if (filter.length) {
console.log(filter[0].name)
console.log(filter[0].Id)
}
else console.log("not found")

Retrieve the value of a nested object that has a changing name with Javascript

I am having trouble trying to get a value from a list of objects in a Woocommerce webhook. Woocommerce inputs the order number of the selected dropdown (ie.Royal Mail is 5th in the dropdown, USPS is 3rd) so I need to be able to access this when it is any value.
var labelchoice = event.line_items[0].meta_data[1].value[0].label; // SUCCESS This returns "Custom"
var labelchoice1 = event.line_items[0].meta_data[1].value[0].value[0].value.5.value; // FAILED with "Unexpected Number"
var labelchoice2 = event.line_items[0].meta_data[1].value[0].value.value.5.value; // FAILED with "Unexpected Number"
var labelchoice3 = event.line_items[0].meta_data[1].value[0].value[0].value[0].5.value; // FAILED with "Unexpected Number"
var labelchoice4 = event.line_items[0].meta_data[1].value[0].value[0].value[0].5[0].value; // FAILED with "Unexpected Number"
The number "5" that is referenced is the number of the dropdown option (there are 8 options eg. USPS, Airmail etc) on a product page. The problem here is I don't know what the number is going to be selected (the dropdown the customer chooses) so that "5" object needs to be perhaps referenced as a wildcard as it could be any number from 1-8.
Can anyone help me grab that nested "label" value? - shown in the example as "Royal Mail"
"meta_data": [
{
"id": 166,
"key": "Dropdown options",
"value": "Custom"
},
{
"id": 167,
"key": "_WCPA_order_meta_data",
"value": [
{
"type": "select",
"name": "select-1549626172813",
"label": "Custom",
"value": {
"5": {
"i": 5,
"value": "UK-RM",
"label": "Royal Mail"
}
},
In case the property name (5) is not known, it can be queried:
var labelchoiceX = event.line_items[0].meta_data[1].value[0].value[
Object.keys(event.line_items[0].meta_data[1].value[0].value)[0]
].label;
You can pass the index as a string variable
const index = '5' // or any other value from the select dropdown
const labelchoice = event.line_items[0].meta_data[1].value[0].value[index].label
Here's in action: https://codepen.io/herodrigues/pen/RvYqeL
You are after the [] property access syntax.
const m = new Map();
for (let i = 1; i <= 8; i++) {
m.set(i,
event.line_items[0].meta_data[1].value[0].value[String(i)].value /* or .label? */);
}
Try this. I think this is the correct order:
var labelchoice = event.line_items[0].meta_data[1].value[0].value.5.label;

Append one value from array of lists - react native

This API require me to send some data comma separated, when handling the user input I use checkboxes like so
<SelectMultiple
items={dairy}
selectedItems={this.state.selectedIngredients}
onSelectionsChange={this.onSelectionsChange} />
I can definitely see the inputs if I render selectedIngredients on a FlatList (using item.value) but when I try to print the actual url I am working with I got this [object,Object]
I used this.state.selectedIngredients in the view, here is the result:
url.com/api/?=[object Object],[object Object],[object Object]
Inside my search function I use that code to handle user inputs:
const { selectedIngredients } = this.state;
let url = "url.com/api/?i=" + selectedIngredients
In the documentation of the library they say the selected items is type array of string or { label, value } I used the method provided there to append the selected items:
onSelectionsChange = (selectedIngredients) => {
// selectedFruits is array of { label, value }
this.setState({ selectedIngredients})
}
I tried adding .value on both of them it didn't solve my problem. Could anyone one help please?
Console log this.state.selectedIngredients:
Array [
Object {
"label": "Goat cheese",
"value": "Goat cheese",
},
Object {
"label": "Cream cheese",
"value": "Cream cheese",
},
Object {
"label": "Butter",
"value": "Butter",
},
]
selectedIngredients = [
{
"label": "Goat cheese",
"value": "Goat cheese",
},
{
"label": "Cream cheese",
"value": "Cream cheese",
},
{
"label": "Butter",
"value": "Butter",
},
]
let selectedValues = selectedIngredients.map((ingredient)=> ingredient.value)
let selectedValuesInString = selectedValues.join(',');
console.log(selectedValuesInString)
It's a bit clumsy, but it'll give you a comma-separated string with no trailing comma.
const { selectedIngredients } = this.state;
let sep = "";
let selectedIngAsString = "";
selectedIngredients.forEach(s => {
selectedIngAsString += sep + s.value;
sep = ",";
});
let url = "url.com/api/?i=" + selectedIngAsString
See https://codesandbox.io/s/m5ynqw0jqp
Also, see Mohammed Ashfaq's for a much less clumsy answer.

change row background color Jquery

I have called a webapi and I got json data
{
"orderId": 26,
"userId": "53cf1e15",
"user": {
"editablePropertyNames": [],
"email": "rajesh#tech.com",
"firstName": "Rajesh",
"id": "53cf1e15",
"identities": [],
"lastName": "kumar",
"missingProperties": [],
"phoneNumber": "45877298"
},
"locationId": 4024,
"pickupType": 1,
"pickupTimeUtc": "2015-11-27T17:33:00.417"
},
{
"orderId": 601,
"userId": "06bf5983",
"user": {
"editablePropertyNames": [],
"email": "rtest#wa.com",
"firstName": "Rakesh",
"id": "06bf5983",
"identities": [],
"lastName": "Pkumar",
"missingProperties": [],
},
"locationId": 424,
"pickupType": 1,
"pickupTimeUtc": "2016-11-16T21:30:00",
"total": 4.32,
"tax": 0.83
}
var PickupMethodEnum = _enum({
DineIn: 1, DriveThru: 2, TakeOut: 3
})
index.html
I have 5 columns
#imageIndicator Name PickupName Total scheduledTime
car.png Kumar 1 4.32 2015-11-27T17:33:00.417
my problem is
I want to display value instead of "1" in pickupName column. ( DineIn: 1, DriveThru: 2, TakeOut: 3).
show image in #imageindicaor column if pickupName ="DriveThru" otherwise hide the image.
show scheduledTime in custom format
if scheduledTime is current date then display as 12:15 pm.
if scheduled time is tomorrow date the display as 8/10 - 7:00am.
if pickupName ="TakeOut" then change that` row background color to gray and then remove that row after 2 minutes.
I want to display value instead of "1" in pickupName column. ( DineIn: 1, DriveThru: 2, TakeOut: 3).
Object.keys( objectName )[ propertyIndex ]
will return the desired property's name
The rest of your issues can be resolved with conditional statements once you've obtained the JSON data. You haven't provided your attempt so there isn't much to work with.
Hi for first point you need to write your enum properly numbers:"String" because you are getting numbers from JSON.
//Global Object
var pickupNameEnum = {
0: "DineIn",
1: "DriveThru",
2: "TakeOut"
};
Write a function as showRow(singleRowObject) in which while traversing your JSON
function showRow(singleRowObject){
var imageString="";
var hideImage=false;
var showString='';
var retutnObject={};
if(pickupNameEnum[singleRowObject.pickupType]!=undefiend){
showString='DineIn';
//DineIn
}else if(singleRowObject.pickupType==){
//DriveThru
showString='DriveThru';
imageString="<img src='abc.png' alt='img'></img>";
}else if(singleRowObject.pickupType==){
//TakeOut and change Color on basis of this flag
hideImage=true;
showString='TakeOut ';
}
retutnObject.hideImage=hideImage;
retutnObject.imageString=imageString;
retutnObject.showString=showString;
}
For date split dateString and refer to this question
For Removing Row change refer this

Reading from a JSON object via Javascript syntax [duplicate]

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 7 years ago.
I am trying to read some values from a JSON object and use them to populate an html template. I can seem to figure out the right syntax to read from the JSON file. For example, when I want to read in the first object's "role", I write:
console.log("first object: "+ ((obj[0].roles)[0]).name)
The above works and returns "first object: thing commented on".
Then when I try to read the text of the verb under the "srcLanguageSentence" within the first object, I write:
console.log("first verb: "+ ((obj[0].srcLanguageSentence.verb[2]).text)
I expect to see "first verb: comment" but that does not happen. Where is my syntax wrong here?Please see a snippet of the JSON object file below:
[
{
"description": "",
"roles": [
{
"name": "thing commented on"
},
{
"name": "commentor"
}
],
"srcLanguageSentence": {
"roles": [
{
"beginOffset": 23,
"endOffset": 30,
"name": "thing commented on",
"text": "on them"
},
{
"beginOffset": 5,
"endOffset": 7,
"name": "commentor",
"text": "We"
}
],
"text": " `` We wo n't comment on them . '' ",
"verb": {
"beginOffset": 15,
"endOffset": 22,
"text": "comment"
}
},
"tgtLanguageSentences": [
{
"roles": [
{
"beginOffset": 1,
"endOffset": 31,
"name": "thing commented on",
"text": "Weitere Aspekte der Kommission"
},
{
"beginOffset": 44,
"endOffset": 47,
"name": "commentor",
"text": "ich"
},
{
"beginOffset": 48,
"endOffset": 55,
"name": "negation",
"text": "nicht ."
}
],
"text": " Weitere Aspekte der Kommission kommentiere ich nicht . ",
"verb": {
"beginOffset": -1,
"endOffset": -1,
"sense": "COMMENT, intransitive",
"text": "kommentieren"
}
}
],
"verb": "KOMMENTIEREN"
},
]
Use:
console.log("first verb: "+ obj[0].srcLanguageSentence.verb.text)
Instead of:
console.log("first verb: "+ ((obj[0].srcLanguageSentence.verb[2]).text)
In general, you need to use the bracket notation [] when accessing an array and the dot notation (.something) when accessing a property of an object. In JSON, an array is indicated by [] while an object is indicated by {}. Those two simple rules make it easy to figure out how to access nested values typically seen in complex JSON objects.
Note that in practice, you can use bracket notation when access an object. For example, say we have this object:
var obj = { x: 10 };
I can do console.log(obj['x']) or console.log(obj.x) and either will work. This makes it possible to programmatically access an object. Say like this:
var obj = {
x: 10,
y: 30,
z: -2
};
Object.keys(obj).forEach(function(key) {
console.log(obj[key]);
});
There we loop over the keys (['x', 'y', 'z']) and can then use the bracket notation to access the values. We can't do obj.key because that would lookup key in the object -- not the value of key.
console.log("first verb: "+ obj[0].srcLanguageSentence.verb.text)
console.log("first verb: "+ ((obj[0].srcLanguageSentence.verb[2]).text) should be:
console.log("first verb: "+ obj[0].srcLanguageSentence.verb.sense.text.split(', ')[0].toLowerCase());
That's if your desired output is first verb: comment.

Categories