How to GET multiple parameters with different structure (Array and Int ,etc) in spray - arrays

I want to get multiple parameters such as Array of String and integer in spray,for example:
http://localhost:8088/sWrite?name=book1&name=book2&name=book3&number=5&TF=false
I use below code:
path("sWrite") {
get {
parameters('name.as[Array[String]], 'number.as[Int], 'TF.as[Boolean]) {
(name, number, TF) =>
complete {
"ok"
}
}
}
}
But it's lead to this error:
[error] too many arguments for method parameters: (pdm spray.routing.directives.ParamDefMagnet)pdm.Out
How can i get array of string and integer in spray??

Should be used from paramString:
path("sWrite") {
def paramString(param: (String, String)): String = s"""${param._1} = '${param._2}'"""
parameterSeq {
params =>
complete {
val sr = params.toArray
val sw = tRest.seqWrite(Seq(sr(0)._2, sr(1)._2, sr(2)._2), sr(3)._2.toInt, sr(4)._2.toBoolean)
"Sequence Write Successful"
}
}

Here's a custom directive to extract multiple query parameters with the same name into a Seq[String]:
def multiParameter(param: Symbol): Directive1[Seq[String]] = {
extract(_.request.uri.query.collect {
case (key, value) if key == param.name => value
}).flatMap {
case Nil => reject(MissingQueryParamRejection(param.name))
case x => provide(x)
}
}
It doesn't support all the bells and whistles that the parameter family of directives do, like optionality, defaults, and type conversion. But you can maybe do some of that by hand if you need to.
Anyway, using this directive to solve the original problem looks like this:
path("sWrite") {
get {
multiParameter('name) { name => // is a Seq, but you can do name.toArray
parameters('number.as[Int], 'TF.as[Boolean]) { (number, TF) =>
complete { "ok" }
}
}
}
}

Related

React : Pushing result of map() to an array

Hello I am trying to map through an array of objects and push them to a new array.
My ISSUE : only the last item of the object is being pushed to the new array
I believe this has to do with React life cycle methods but I don't know where I should I loop and push the values to the array to get the full list
//My object in an array named states
var states = [{"_id":"Virginia","name":"Virginia","abbreviation":"VN","__v":0},{"_id":"North Carolina","name":"North Carolina","abbreviation":"NC","__v":0},{"_id":"California","name":"California","abbreviation":"CA","__v":0}];
export function StateSelect()
{
**EDIT 1**
const options = [];
function getStates()
{
//This is how I am looping through it and adding to an array
{ states.length > 0 &&
states.map(item =>
(
console.log(`ITEM: ${JSON.stringify(item)}`),
options.push([{ value: `${item.name}`, label: `${item.name}`}])
))
}
}
return( {getStates()}: );
}
Thank you
It looks like your getStates() might not even be returning anything... but assuming it is, I believe you should be able to accomplish this using a forEach() fn in order to push values into your options array... Try adding the following into your map:
states.map((item) => {
console.log(`ITEM: ${JSON.stringify(item)}`);
let processed = 0;
item.forEach((i) => {
options.push([{ value: `${i.name}`, label: `${i.name}`}]);
processed++;
if(processed === item.length) {
// callback fn, or return
}
}
.map usually used to return another result, you could just use .forEach
In fact, you don't really need to declare options at all, just use .map on state to return the result would be fine.
return states.length > 0 && states.map(({ name }) => {
return { value: name, label: name };
});

Pass an Array as a query String Parameter node.js

How can I pass an array as a query string parameter?
I've tried numerous ways including adding it to the path but i'm not able to pull the array on the back end.
If I hard code the array it works fine, but when I try to pass the array from my front end to the backend it does not work properly.
Can anyone point me in the right direction?
FrontEnd
function loadJob() {
return API.get("realtorPilot", "/myTable/ListJobs", {
'queryStringParameters': {
radius,
availableServices,
}
});
BackEnd
import * as dynamoDbLib from "./libs/dynamodb-lib";
import { success, failure } from "./libs/response-lib";
export async function main(event, context) {
const data = {
radius: event.queryStringParameters.radius,
availableServices: event.queryStringParameters.availableServices,
};
// These hold ExpressionAttributeValues
const zipcodes = {};
const services = {};
data.radius.forEach((zipcode, i) => {
zipcodes[`:zipcode${i}`] = zipcode;
});
data.availableServices.forEach((service, i) => {
services[`:services${i}`] = service;
});
// These hold FilterExpression attribute aliases
const zipcodex = Object.keys(zipcodes).toString();
const servicex = Object.keys(services).toString();
const params = {
TableName: "myTable",
IndexName: "zipCode-packageSelected-index",
FilterExpression: `zipCode IN (${zipcodex}) AND packageSelected IN (${servicex})`,
ExpressionAttributeValues : {...zipcodes, ...services},
};
try {
const result = await dynamoDbLib.call("scan", params);
// Return the matching list of items in response body
return success(result.Items);
} catch (e) {
return failure(e.message);
}
}
Pass a comma seperated string and split it in backend.
Example: https://example.com/apis/sample?radius=a,b,c,d&availableServices=x,y,z
And in the api defenition split the fields on comma.
const data = {
radius: event.queryStringParameters.radius.split(','),
availableServices: event.queryStringParameters.availableServices.split(',')
};

Searching JSON array using another JSON array node js

I'm trying to filter a JSON array using another JSON array criteria that I have using (filter).
Here is my code:
function filterArray(object, criteria){
return object.filter(function(obj){
for(var i=0;i<criteria.length;i++){
let criteriaEle = criteria[i];
return Object.keys(criteriaEle).forEach(function(key){
if(obj[key] == criteriaEle[key]){
return obj;
}
})
}
})
}
For example:
object = [{type:1,company:1,color:0,name:a},{type:2,company:1,color:0,name:b},{type:1,company:3,color:0,name:c},{type:4,company:1,color:0,name:d},{type:1,company:1,color:1,name:e}]
criteria = [{type:1,company:1,color:0},{type:1,company:1,color:1}]
So if I give these two arrays to the function it should return
obj = [{{type:1,company:1,color:0,name:a},{type:1,company:1,color:1,name:e}}]
I'm not sure where am I going wrong in this. Please help.
Update:
Also, I do not want to use obj.type or obj.company or object.color as parameters to search as I want to make my code maintainable and do not want to come and update it later if in future more criteria's are added.
const data = [{type:1,company:1,color:0,name:'a'},{type:2,company:1,color:0,name:'b'},{type:1,company:3,color:0,name:'c'},{type:4,company:1,color:0,name:'d'},{type:1,company:1,color:1,name:'e'}];
const criteria = [{type:1,company:1,color:0},{type:1,company:1,color:1}];
function checkCriteria(obj) {
return criteria.some(criterion => {
for (const key in criterion) {
if (criterion[key] !== obj[key]) {
return false;
}
}
return true;
});
}
const filtered = data.filter(checkCriteria);
console.log('Filtered array: ', filtered);
Here is one solution.
Here are some references
Array.some
Array.filter
Based on the comment, adding another snippet to explain the concept of closures.
const data = [{type:1,company:1,color:0,name:'a'},{type:2,company:1,color:0,name:'b'},{type:1,company:3,color:0,name:'c'},{type:4,company:1,color:0,name:'d'},{type:1,company:1,color:1,name:'e'}];
function createCriteriaValidationFunction(criteria) {
return function checkCriteria(obj) {
return criteria.some(criterion => {
for (const key in criterion) {
if (criterion[key] !== obj[key]) {
return false;
}
}
return true;
});
}
}
const criteria = [{type:1,company:1,color:0},{type:1,company:1,color:1}];
const filtered = data.filter(createCriteriaValidationFunction(criteria));
console.log('Filtered array: ', filtered);
It's the same concept as before, however, criteria was defined in the file. This time, criteria can be defined outside and can be passed in to the function. The trick is to create the checkCriteria function on the fly with criteria passed in and available in the closure. In both cases, criteria variable is available in the scope in which checkCriteria is executed.

How to check a specific prop-type against a specific value?

Calling prop-types directly has been deprecated. They now recommend you check a component's props like this:
PropTypes.checkPropTypes(MyComponent.propTypes, props, 'prop', 'MyComponent');
But I need to check a specific value against a specific prop-type.
e.g. I have this code:
export function tuple(...types) {
return requirable(function(props, propName, componentName, location, propFullName) {
let value = props[propName];
if(!location) {
location = 'prop';
}
if(!propFullName) {
propFullName = propName;
}
if(!Array.isArray(value)) {
throw new Error(`Invalid ${location} \`${propFullName}\` supplied to \`${componentName}\`, expected ${types.length}-element array`);
}
if(value.length !== types.length) {
throw new Error(`Invalid ${location} \`${propFullName}\` supplied to \`${componentName}\`, expected ${types.length}-element array, got array of length ${value.length}`);
}
for(let i = 0; i < value.length; ++i) {
if(!types[i](value[i])) {
throw new Error(`Invalid ${location} ${propFullName}[${i}] supplied to \`${componentName}\`, unexpected type`);
}
}
return null;
});
}
And in there it does
if(!types[i](value[i])) {
Where types[i] might be something like PropTypes.string. So I want to check if the first array element is a string, and the second array element is a number.
i.e., I don't have an object full of prop-types, nor a props object in this context. I have one prop-type and one value I want to check.
How can I do that? Does the API not support this use-case anymore?

How to retrieve query parameter in Server Script

I'm using Windows Azure Mobile Service to build the backend for my app. For server script's read operation, now I want to retrieve the query parameter like $filter, $select in the script, etc. Any idea?
After hacking around with the 'query' object in the 'read' function's parameter (by using console.log ), I finally found the solution:
function isObject(variable) {
return variable !== null &&
variable !== undefined &&
typeof variable === 'object';
}
// Find all the member-value pairs from the expression object
function findMemberValuePairsFromExpression (expr, ret) {
if (!isObject(expr)) {
return null;
}
ret = ret || {};
for (var name in expr) {
if (expr.hasOwnProperty(name)) {
var prop = expr[name];
if (name === 'parent') { // Ignore parent property since it's added by us
continue;
}
else if (name === 'left') { // member expression are in the left subtree
if (isObject(prop)) {
prop.parent = expr; // Remember the parent
findMemberValuePairsFromExpression(prop, ret);
}
}
else if (name === 'member') {
// Found a member expression, find the value expression
// by the knowledge of the structure of the expression
var value = expr.parent.right.value;
ret[prop] = value;
}
}
}
if (expr.parent) {
// Remove the added parent property
delete expr.parent;
}
return ret;
}
// Get the filters component from query object and
// find the member-value pairs in it
function findMemberValuePairsFromQuery (query) {
var filters = query.getComponents().filters;
return findMemberValuePairsFromExpression(filters);
}
function read (query, user, request) {
request.execute();
}
Remember that this approach heavily relies on the inner structure of the query object so it may break in the future.
query.getComponents() also returns other parts of the query, like 'select', 'skip', 'top', etc. Basically anything of the oData protocol

Resources