Boolean in a URI query? - http

What is the preferred way to specify boolean value in the query part of URI? A normal query string looks like
a=foo&b=bar
Say I have a parameter "c" with boolean value, should I state
a=foo&b=bar&c=1
Or
a=foo&b=bar&c=True
Or
a=foo&b=bar&c=true
I checked the query component section of RFC 2396 and it does not specify how to express a boolean parameter. So what I want to know is what is the common (or reasonable) way to do it?

It completely depends on the way you read the query string. All of these that you ask for are valid.

Use key existence for boolean parameter like ?foo
For example, use ?foo instead of ?foo=true.
I prefer this way because I don't need to waste time to think or trace the source code about whether it should be true or 1 or enable or yes or anything that beyond my imagination.
In the case of case sensitivity, should it be true or True or TRUE?
In the case of term stemming, should it be enable or enabled?
IMHO, the form of ?foo is the most elegant way to pass a boolean variable to server because there are only 2 state of it (exist or not exist), which is good for representing a boolean variable.
This is also how Elasticsearch implemented for boolean query parameter, for example:
GET _cat/master?v

In node with an express server, you can add a boolean parser middleware like express-query-boolean.
var boolParser = require('express-query-boolean');
// [...]
app.use(bodyParser.json());
app.use(boolParser());
Without
// ?a=true&b[c]=false
console.log(req.query);
// => { a: 'true', b: { c: 'false' } }
With
// ?a=true&b[c]=false
console.log(req.query);
// => { a: true, b: { c: false } }

Url are strings and all values in a URL are strings,
all the params will be returned as strings.
it depends on how you interpret it in your code.
for the last one where c = true
you can do a JSON.parse(c)
which will change it to a boolean.
Also, you have to be careful not to pass it an empty string, if not it will throw an error.

I managed this with a custom function.
See browser compatibility here: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
function parseQuery(url = window.location.search) {
const urlParams = new URLSearchParams(url);
return Array.from(urlParams.keys()).reduce((acc, key) => {
const value = urlParams.get(key);
if (value) {
switch (value) {
case 'false': {
acc[key] = false;
break;
}
case 'true': {
acc[key] = true;
break;
}
case 'undefined': {
acc[key] = undefined;
break;
}
case 'null': {
acc[key] = null;
break;
}
default: {
acc[key] = value;
}
}
}
return acc;
}, {});
}
The function returns an object with all the parsed query parameters and fallback by default to the original value.

Or you can do this
const queryBool = unwrapTextBoolean({{{A_WAY_TO_GET_THAT_TEXT_BOOLEAN}}})
if(queryBool===null) {return;}
if(queryBool){
/*true-based code*/
}else{
/*false-based code*/
}
function unwrapTextBoolean(tB){
if(tB === 'true') return true;
if(tb === 'false') return false;
return null;
}

Related

GET params set to "false" - philosophic question [duplicate]

What is the preferred way to specify boolean value in the query part of URI? A normal query string looks like
a=foo&b=bar
Say I have a parameter "c" with boolean value, should I state
a=foo&b=bar&c=1
Or
a=foo&b=bar&c=True
Or
a=foo&b=bar&c=true
I checked the query component section of RFC 2396 and it does not specify how to express a boolean parameter. So what I want to know is what is the common (or reasonable) way to do it?
It completely depends on the way you read the query string. All of these that you ask for are valid.
Use key existence for boolean parameter like ?foo
For example, use ?foo instead of ?foo=true.
I prefer this way because I don't need to waste time to think or trace the source code about whether it should be true or 1 or enable or yes or anything that beyond my imagination.
In the case of case sensitivity, should it be true or True or TRUE?
In the case of term stemming, should it be enable or enabled?
IMHO, the form of ?foo is the most elegant way to pass a boolean variable to server because there are only 2 state of it (exist or not exist), which is good for representing a boolean variable.
This is also how Elasticsearch implemented for boolean query parameter, for example:
GET _cat/master?v
In node with an express server, you can add a boolean parser middleware like express-query-boolean.
var boolParser = require('express-query-boolean');
// [...]
app.use(bodyParser.json());
app.use(boolParser());
Without
// ?a=true&b[c]=false
console.log(req.query);
// => { a: 'true', b: { c: 'false' } }
With
// ?a=true&b[c]=false
console.log(req.query);
// => { a: true, b: { c: false } }
Url are strings and all values in a URL are strings,
all the params will be returned as strings.
it depends on how you interpret it in your code.
for the last one where c = true
you can do a JSON.parse(c)
which will change it to a boolean.
Also, you have to be careful not to pass it an empty string, if not it will throw an error.
I managed this with a custom function.
See browser compatibility here: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
function parseQuery(url = window.location.search) {
const urlParams = new URLSearchParams(url);
return Array.from(urlParams.keys()).reduce((acc, key) => {
const value = urlParams.get(key);
if (value) {
switch (value) {
case 'false': {
acc[key] = false;
break;
}
case 'true': {
acc[key] = true;
break;
}
case 'undefined': {
acc[key] = undefined;
break;
}
case 'null': {
acc[key] = null;
break;
}
default: {
acc[key] = value;
}
}
}
return acc;
}, {});
}
The function returns an object with all the parsed query parameters and fallback by default to the original value.
Or you can do this
const queryBool = unwrapTextBoolean({{{A_WAY_TO_GET_THAT_TEXT_BOOLEAN}}})
if(queryBool===null) {return;}
if(queryBool){
/*true-based code*/
}else{
/*false-based code*/
}
function unwrapTextBoolean(tB){
if(tB === 'true') return true;
if(tb === 'false') return false;
return null;
}

what is the best practice of Vert.x handler for checking check existence?

I am implementing a method using Vertx to check the existence of certain value in the database and use Handler with AsyncResult.
I would like to know which one is the best practice:
Option 1: When nothing found, Handler is with succeededFuture but with result as FALSE:
public void checkExistence (..., String itemToFind, Handler<AsyncResult<Boolean>> resultHandler) {
// ....
doQuery(..., queryHandler -> {
if (queryHandler.succeeded()) {
List<JsonObject> results = queryHandler.result();
boolean foundIt = false;
for (JsonObject json: results) {
if (json.getString("someKey").equals(itemToFind)) {
foundIt = true;
break;
}
}
resultHandler.handle(Future.succeededFuture(foundIt));
} else {
resultHandler.handle(Future.failedFuture(queryHandler.cause().toString()));
}
});
}
Option 2: When nothing found, Handler is with failedFuture:
public void checkExistence (..., String itemToFind, Handler<AsyncResult<Void>> resultHandler) {
// ....
doQuery(..., queryHandler -> {
if (queryHandler.succeeded()) {
List<JsonObject> results = queryHandler.result();
boolean foundIt = false;
for (JsonObject json: results) {
if (json.getString("someKey").equals(itemToFind)) {
foundIt = true;
break;
}
}
// HERE IS THE DIFFERENCE!!!
if (foundIt) {
resultHandler.handle(Future.succeededFuture());
} else {
resultHandler.handle(Future.failedFuture("Item " + itemToFind + " not found!"));
}
} else {
resultHandler.handle(Future.failedFuture(queryHandler.cause().toString()));
}
});
}
UPDATE:
Let's say I have another example, instead of checking the existence, I would like to get all the results. Do I check the Empty results? Do I treat Empty as failure or success?
Option 1: only output them when it's not null or empty, otherwise, fail it
public void getItems(..., String itemType, Handler<AsyncResult<List<Item>>> resultHandler) {
// ....
doQuery(..., queryHandler -> {
if (queryHandler.succeeded()) {
List<Item> items = queryHandler.result();
if (items != null && !items.empty()) {
resultHandler.handle(Future.succeededFuture(items));
} else {
resultHandler.handle(Future.failedFuture("No items found!"));
}
} else {
resultHandler.handle(Future.failedFuture(queryHandler.cause().toString()));
}
});
}
Option 2: output results I got, even though it could be empty or null
public void getItems(..., String itemType, Handler<AsyncResult<List<Item>>> resultHandler) {
// ....
doQuery(..., queryHandler -> {
if (queryHandler.succeeded()) {
List<Item> items = queryHandler.result();
resultHandler.handle(Future.succeededFuture(items));
} else {
resultHandler.handle(Future.failedFuture(queryHandler.cause().toString()));
}
});
}
The 1st one option is better, because you can clearly say, that checkExistence returned True or False and completed successfully or it failed with some exception (database issue, etc.).
But lets say, you've decided to stick with 2nd option. Then, imagine you have another method:
void getEntity(int id, Handler<AsyncResult<Entity>> resultHandler);
If entity with provided id doesn't exists, will you throw exception (using Future.failedFuture) or return null (using Future.succeededFuture)? I think, you should throw exception to make your methods logic similar to each other. But again, is that exceptional situation?
For case with returning list of entities you can just return empty list, if there are no entities. Same goes to single entity: it's better to return Optional<Entity> instead of Entity, because in this way you avoid NullPointerException and don't have nullable variables in the code. What's better: Optional<List<Entity>> or empty List<Entity>, it's open question.
Particularly if you're writing this as reusable code, then definitely go with your first option. This method is simply determining whether an item exists, and so should simply return whether it does or not. How is this particular method to know whether it's an error condition that the item doesn't exist?
Some caller might determine that it is indeed an error; it that's the case, then it will throw an appropriate exception if the Future returns with false. But another caller might simply need to know whether the item exists before proceeding; in that case, you'll find yourself using exception handling to compose your business logic.

Swift 3: Sort (formerly sort-in-place) array by sort descriptors

Until now (Swift 2.2) I have been happily using the code from this answer - it's swifty, it's elegant, it worked like a dream.
extension MutableCollectionType where Index : RandomAccessIndexType, Generator.Element : AnyObject {
/// Sort `self` in-place using criteria stored in a NSSortDescriptors array
public mutating func sortInPlace(sortDescriptors theSortDescs: [NSSortDescriptor]) {
sortInPlace {
for sortDesc in theSortDescs {
switch sortDesc.compareObject($0, toObject: $1) {
case .OrderedAscending: return true
case .OrderedDescending: return false
case .OrderedSame: continue
}
}
return false
}
}
}
extension SequenceType where Generator.Element : AnyObject {
/// Return an `Array` containing the sorted elements of `source`
/// using criteria stored in a NSSortDescriptors array.
#warn_unused_result
public func sort(sortDescriptors theSortDescs: [NSSortDescriptor]) -> [Self.Generator.Element] {
return sort {
for sortDesc in theSortDescs {
switch sortDesc.compareObject($0, toObject: $1) {
case .OrderedAscending: return true
case .OrderedDescending: return false
case .OrderedSame: continue
}
}
return false
}
}
}
Swift 3 changes everything.
Using the code migration tool and Proposal SE- 0006 - sort() => sorted(), sortInPlace() => sort() - I have gotten as far as
extension MutableCollection where Index : Strideable, Iterator.Element : AnyObject {
/// Sort `self` in-place using criteria stored in a NSSortDescriptors array
public mutating func sort(sortDescriptors theSortDescs: [SortDescriptor]) {
sort {
for sortDesc in theSortDescs {
switch sortDesc.compare($0, to: $1) {
case .orderedAscending: return true
case .orderedDescending: return false
case .orderedSame: continue
}
}
return false
}
}
}
extension Sequence where Iterator.Element : AnyObject {
/// Return an `Array` containing the sorted elements of `source`
/// using criteria stored in a NSSortDescriptors array.
public func sorted(sortDescriptors theSortDescs: [SortDescriptor]) -> [Self.Iterator.Element] {
return sorted {
for sortDesc in theSortDescs {
switch sortDesc.compare($0, to: $1) {
case .orderedAscending: return true
case .orderedDescending: return false
case .orderedSame: continue
}
}
return false
}
}
}
The 'sorted' function compiles [and works] without problems. For 'sort' I get an error on the line that says 'sort' : "Cannot convert value of type '(_, _) -> _' to expected argument type '[SortDescriptor]'" which has me completely baffled: I do not understand where the compiler is trying to convert anything since I am passing in an array of SortDescriptors, which ought to BE an array of SortDescriptors.
Usually, this type of error means that you're handling optionals where you ought to have definite values, but since this is a function argument - and seems to work without a hitch in func sorted - all I can read from it is that 'something is wrong'. As of now, I have no idea WHAT that something is, and since we're in the early stages of beta, there is no documentation at all.
As a workaround, I have removed the sort (formerly sort-in-place) function from my code and replaced it with a dance of
let sortedArray = oldArray(sorted[...]
oldArray = sortedArray
but I'd be really grateful if I could get my sort-in-place functionality back.
Compare the methods available in Swift 2.2:
with the methods in Swift 3:
Notice that Swift 3 does not have a sort method that accepts an isOrderedBefore closure.
That is why your function won't compile.
This looks like a bug, so I reported it as bug 26857748 at bugreport.apple.com.
let sortedArray = users.sorted { $0.name < $1.name }
Use RandomAccessCollection protocol
extension MutableCollection where Self : RandomAccessCollection {
/// Sort `self` in-place using criteria stored in a NSSortDescriptors array
public mutating func sort(sortDescriptors theSortDescs: [NSSortDescriptor]) {
sort { by:
for sortDesc in theSortDescs {
switch sortDesc.compare($0, to: $1) {
case .orderedAscending: return true
case .orderedDescending: return false
case .orderedSame: continue
}
}
return false
}
}
}
In Swift 3.0
let sortedCapitalArray = yourArray.sorted {($0 as AnyObject).localizedCaseInsensitiveCompare(($1 as AnyObject)as! String) == ComparisonResult.orderedAscending}

How can I use a Swift enum as a Dictionary key? (Conforming to Equatable)

I've defined an enum to represent a selection of a "station"; stations are defined by a unique positive integer, so I've created the following enum to allow negative values to represent special selections:
enum StationSelector : Printable {
case Nearest
case LastShown
case List
case Specific(Int)
func toInt() -> Int {
switch self {
case .Nearest:
return -1
case .LastShown:
return -2
case .List:
return -3
case .Specific(let stationNum):
return stationNum
}
}
static func fromInt(value:Int) -> StationSelector? {
if value > 0 {
return StationSelector.Specific(value)
}
switch value {
case -1:
return StationSelector.Nearest
case -2:
return StationSelector.LastShown
case -3:
return StationSelector.List
default:
return nil
}
}
var description: String {
get {
switch self {
case .Nearest:
return "Nearest Station"
case .LastShown:
return "Last Displayed Station"
case .List:
return "Station List"
case .Specific(let stationNumber):
return "Station #\(stationNumber)"
}
}
}
}
I'd like to use these values as keys in a dictionary. Declaring a Dictionary yields the expected error that StationSelector doesn't conform to Hashable. Conforming to Hashable is easy with a simple hash function:
var hashValue: Int {
get {
return self.toInt()
}
}
However, Hashable requires conformance to Equatable, and I can't seem to define the equals operator on my enum to satisfy the compiler.
func == (lhs: StationSelector, rhs: StationSelector) -> Bool {
return lhs.toInt() == rhs.toInt()
}
The compiler complains that this is two declarations on a single line and wants to put a ; after func, which doesn't make sense, either.
Any thoughts?
Info on Enumerations as dictionary keys:
From the Swift book:
Enumeration member values without associated values (as described in
Enumerations) are also hashable by default.
However, your Enumeration does have a member value with an associated value, so Hashable conformance has to be added manually by you.
Solution
The problem with your implementation, is that operator declarations in Swift must be at a global scope.
Just move:
func == (lhs: StationSelector, rhs: StationSelector) -> Bool {
return lhs.toInt() == rhs.toInt()
}
outside the enum definition and it will work.
Check the docs for more on that.
I struggled for a little trying to make an enum with associated values conform to Hashable.
Here's I made my enum with associated values conform to Hashable so it could be sorted or used as a Dictionary key, or do anything else that Hashable can do.
You have to make your associated values enum conform to Hashable because associated values enums cannot have a raw type.
public enum Components: Hashable {
case None
case Year(Int?)
case Month(Int?)
case Week(Int?)
case Day(Int?)
case Hour(Int?)
case Minute(Int?)
case Second(Int?)
///The hashValue of the `Component` so we can conform to `Hashable` and be sorted.
public var hashValue : Int {
return self.toInt()
}
/// Return an 'Int' value for each `Component` type so `Component` can conform to `Hashable`
private func toInt() -> Int {
switch self {
case .None:
return -1
case .Year:
return 0
case .Month:
return 1
case .Week:
return 2
case .Day:
return 3
case .Hour:
return 4
case .Minute:
return 5
case .Second:
return 6
}
}
}
Also need to override the equality operator:
/// Override equality operator so Components Enum conforms to Hashable
public func == (lhs: Components, rhs: Components) -> Bool {
return lhs.toInt() == rhs.toInt()
}
For more readability, let's reimplement StationSelector with Swift 3:
enum StationSelector {
case nearest, lastShown, list, specific(Int)
}
extension StationSelector: RawRepresentable {
typealias RawValue = Int
init?(rawValue: RawValue) {
switch rawValue {
case -1: self = .nearest
case -2: self = .lastShown
case -3: self = .list
case (let value) where value >= 0: self = .specific(value)
default: return nil
}
}
var rawValue: RawValue {
switch self {
case .nearest: return -1
case .lastShown: return -2
case .list: return -3
case .specific(let value) where value >= 0: return value
default: fatalError("StationSelector is not valid")
}
}
}
The Apple developer API Reference states about Hashable protocol:
When you define an enumeration without associated values, it gains Hashable conformance automatically, and you can add Hashable conformance to your other custom types by adding a single hashValue property.
Therefore, because StationSelector implements associated values, you must make StationSelector conform to Hashable protocol manually.
The first step is to implement == operator and make StationSelector conform to Equatable protocol:
extension StationSelector: Equatable {
static func == (lhs: StationSelector, rhs: StationSelector) -> Bool {
return lhs.rawValue == rhs.rawValue
}
}
Usage:
let nearest = StationSelector.nearest
let lastShown = StationSelector.lastShown
let specific0 = StationSelector.specific(0)
// Requires == operator
print(nearest == lastShown) // prints false
print(nearest == specific0) // prints false
// Requires Equatable protocol conformance
let array = [nearest, lastShown, specific0]
print(array.contains(nearest)) // prints true
Once Equatable protocol is implemented, you can make StationSelector conform to Hashable protocol:
extension StationSelector: Hashable {
var hashValue: Int {
return self.rawValue.hashValue
}
}
Usage:
// Requires Hashable protocol conformance
let dictionnary = [StationSelector.nearest: 5, StationSelector.lastShown: 10]
The following code shows the required implementation for StationSelector to make it conform to Hashable protocol using Swift 3:
enum StationSelector: RawRepresentable, Hashable {
case nearest, lastShown, list, specific(Int)
typealias RawValue = Int
init?(rawValue: RawValue) {
switch rawValue {
case -1: self = .nearest
case -2: self = .lastShown
case -3: self = .list
case (let value) where value >= 0: self = .specific(value)
default: return nil
}
}
var rawValue: RawValue {
switch self {
case .nearest: return -1
case .lastShown: return -2
case .list: return -3
case .specific(let value) where value >= 0: return value
default: fatalError("StationSelector is not valid")
}
}
static func == (lhs: StationSelector, rhs: StationSelector) -> Bool {
return lhs.rawValue == rhs.rawValue
}
var hashValue: Int {
return self.rawValue.hashValue
}
}
As of Swift 5.5 you can just write enum StationSelector: Hashable {}. Automatic conformance will be synthesized.
Just for emphasising what Cezar said before. If you can avoid having a member variable, you don't need to implement the equals operator to make enums hashable – just give them a type!
enum StationSelector : Int {
case Nearest = 1, LastShown, List, Specific
// automatically assigned to 1, 2, 3, 4
}
That's all you need. Now you can also initiate them with the rawValue or retrieve it later.
let a: StationSelector? = StationSelector(rawValue: 2) // LastShown
let b: StationSelector = .LastShown
if(a == b)
{
print("Selectors are equal with value \(a?.rawValue)")
}
For further information, check the documentation.

Can we compare two java collections with dynamic equals method?

Lets say we have a 'Client' object:
(am just mentioning the attributes and the equals method alone of the 'Client' object below!!)
public class Client {
private Long clientId;
private String clientName;
private Integer status;
//getters and setters for above attributes
.....
...
//hashCode method
....
..
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Client other = (Client) obj;
if (clientId == null) {
if (other.clientId != null)
return false;
} else if (!clientId.equals(other.clientId))
return false;
if (clientName == null) {
if (other.clientName != null)
return false;
} else if (!clientName.equals(other.clientName))
return false;
if (status == null) {
if (other.status != null)
return false;
} else if (!status.equals(other.status))
return false;
return true;
}
}
From the above equals method itz clear that 'two' client objects are said to be equal if all the attributes of the two objects are identical.
Now assume a scenario where I need to compare two collections(named say incomingClients and existingClients) of Client objects.
The first collection(Collection incomingClients) was generated after reading the 'client' data from a csv/xls file.
The second collection(Collection existingClients) contains, all the existing clients currently in the system.
I can do the following code (using apache CollectionUtils)to get the 'common' clients.
Collection<Client> commonClients = (Collection<Client>)CollectionUtils.intersection(incomingClients,existingClients);
Now with the below code I can remove these commonClients from both the collections.
incomingClients.removeAll(commonClients);
existingClients.removeAll(commonClients);
The intention of removing the 'common clients objects' was that, we dont need to do 'any processing' for these records,
as we are really not at all interested in those records.
Now how can I figure out which are the entirely 'new clients' in the 'Collection incomingClients' collection?
(When I say 'new' it means a client having a new 'clientId' which doesnt exist in the 'Collection existingClients')
Also, how can I figure out which are the clients which needs 'modification'
(When I say 'modification' it means that the 'Collection incomingClients' and Collection existingClients'
have the same clientId, but, say, different 'clientName')
I know that we can do the normal 'for' loop('check below') to figure out the 'new'/'modification needed' clients.
But I thought of writing 'something new', whether we can achieve this using some classes/function in the 'Apache CollectionUtils' package.
Collection<Client> newClients = new ArrayList<Client>();
Collection<Client> toBeModifiedClients = new ArrayList<Client>();
boolean foundClient = false;
Client client = null;
for(Client incomingClient :incomingClients){
foundClient = false;
for(Client existingClient : existingClients){
if(existingClient.getClientId().equals(incomingClient.getClientId())){
client = existingClient;
foundClient = true;
break;
}
}
if(foundClient){
toBeModifiedClients.add(client);
}else{
//not found in existing. so this is completely new
newClients.add(incomingClient);
}
}
Am I 'complicating' a simple stuff??
Any thoughts??
First, yes, you are complicating "simple stuff". Your entire question could be summarized as follows:
Given collections A and B, how can I get the following using CollectionUtils:
A-B, using a particular function that determines equality
A∩B, using a particular function that determines equality
So, yes. CollectionUtils has what you need. Look at CollectionUtils.select().

Resources