I have the object:
{
"items": [ null, 1, 2 ]
}
and two versions of query strings for it:
array=null&array=1&array=2
array=&array=1&array=2
Which of them is proper? Is there any commonly used convention for this case?
Upd: the problem with null is that ASP.NET interprets it as "null" string.
It depends entirely on what the recipient application expects and parses.
The thing is, though, receiving "null", "false" etc from the query string will of course be interpreted as a string value, and therefore falsy.
So in the URL some_script.php?foo=false
if (!empty($_GET['foo'])) //true - contaisn "false", a string, not a boolean
If you want to be sure the parameter is therefore evaluated to falsy, I would suggest passing it empty.
Related
I am working on a 'typeahead’ type function which will check my Database with the current typed text to provide search suggestions of users using Felgo.
Here is the link for Felgos Firebase documentation
As to not search every entry I am looking to use the startAt and limitTo for a lower data use.
However when applying the startAt my searches only return undefined, I have tried testing this by changing my startAt from a variable to explicit data but this still only returns undefined.
My function is below:
function searchUsers(searchString) {
db.getValue("public/nameList/", {
orderByChild: true,
startAt: searchString, //searchString is a variable with my .currentText to search.
limitToFirst: 10,
}, function(success, key, value) {
if(success) {
searchArr = []
searchArr = value
console.debug("Read user value for key", key, "from DB:", value)
}
})
}
I have also tried by passing my var searchString through JSON.stringify(searchString) and also return undefined!
Removing the startAt: query entirely returns the entire result of nameList as expected, but no matter how I try to implement my startAt it always returns undefined.
A sample of my nameList JSON is:
nameList: {
"EddieLaw245" : 530343772383,
"EddieLawrence91" : 530343772385,
"EdwardL91" : 530343772386,
"EdwardLaw" : 530343772384,
"Edwardlawrence91" : 530343772380,
"JoBrownLondon" : 530343772381,
"KatiePrescottHair" : 543592635596,
"Tracey-Sweeting" : 530343772382
}
So with the above example, When I type E it should remove the last 3 entries, and so on.
The problem is that you're specifying orderByChild: true. If we look at the documentation of that:
orderByChild: If present, the queried object will have its properties ordered by values at sub-paths defined by the value of this property. Ordering by child properties makes the filter properties startAt, endAt and equalTo filter by the child property values
It may not be immediately clear from this, but orderByChild allows you to order the results on a property value under each of those nodes. So your code tries to order the child nodes on the value of a property true, which isn't possible (and should actually generate a compile-time error in the library) as the nodes under nameList don't have any child properties of their own. They merely have a key and a value.
What you're looking for is orderByKeys, which orders the child nodes on their keys. So:
db.getValue("public/nameList/", {
orderByKeys: true,
startAt: searchString,
limitToFirst: 10,
}
You'll typically also want to specify an endAt value, to ensure your type-ahead only shows values that start with the search string. If you only allow ASCII values in the keys, the simplest way to do this is:
startAt: searchString,
endAt: searchString + "~",
The ~ here is no magic operator, but merely the last ASCII characters. If you want to allow a broader character set, you'll need to use the last character in that character set - for example \uF7FF is the last code point for Unicode.
Update from OP
Though I'm certian Franks correct with typical Firebase usage; I suspect due to the Felgo plugin I am using the full solution has a slight adjustment;
db.getValue("public/nameList/", {
"orderByKey": true,
"startAt": searchString,
"endAt": searchString+"~",
"limitToFirst": 10,
}, function(success, key, value) {....}
})
Notes on the above - my filters/queries are surrounded by quotation marks "startAt", also instead of orderByKeys, I have used orderByKey
I'm trying to write unit tests for a rest endpoint with Spring Boot Test that's going well but when I try to assert on an object in the json response with jsonPath an AssertionError is thrown even when contents are identical and the same.
Sample Json
{
"status": 200,
"data": [
{
"id": 1,
"placed_by": 1,
"weight": 0.1,
"weight_metric": "KG",
"sent_on": null,
"delivered_on": null,
"status": "PLACED",
"from": "1 string, string, string, string",
"to": "1 string, string, string, string",
"current_location": "1 string, string, string, string"
}
]
}
Code in Kotlin
mockMvc.perform(
get("/api/v1/stuff")
.contentType(MediaType.APPLICATION_JSON_UTF8)
).andExpect(status().isOk)
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("\$.status").value(HttpStatus.OK.value()))
.andExpect(jsonPath("\$.data.[0]").value(equalTo(stuffDTO.asJsonString())))
That throws AssertionError but the values are the same
Clicking on see difference says
How can I match an object in JSON with jsonPath? I need to be able to match an object because the object can contain many fields and it will be a PITA to match them individually
I came across what looks like the same issue, though it's hard to say without knowing what your asJsonString function is. Also I was using Java, not Kotlin. If it is the same issue:
It's due to jsonPath(expression) not returning a string, so matching it with one doesn't work. You need to convert stuffDTO into the correct type for matching using JsonPath ie. in a function such as:
private <T> T asParsedJson(Object obj) throws JsonProcessingException {
String json = new ObjectMapper().writeValueAsString(obj);
return JsonPath.read(json, "$");
}
Then .andExpect(jsonPath("\$.data.[0]").value(equalTo(asParsedJson(stuffDTO)))) should work.
I have the following JSON string:
{
"myKey": "myValue"
}
I want to check whether this string is not empty. I can do this:
$.myKey
to get the value of myKey. I've tried changing it to
$.[?(#.myKey.length()>0)]
(as per this topic Expression to filter out elements with empty arrays using `jsonPath`) or even this:
$.myKey.length()>0
but I get error that it is not a valid JSONPath expression.
I add "JsonPath Match" to the test step in my project. When I set it to
$.myKey
and press "Select from current", it works. For
$.[?(#.myKey != '')]
when I press "Select from current", I get
"Invalid JsonPath expression"
I use SoapUI 5.4.0 but I don't know how to check its JsonPath implementation. I want to get false if string is empty.
How can I check whether myValue is empty or not? Thanks!
The following jsonpath filter: $.[?(#.myKey != '')] will return the document if the attribute myKey is not an empty string.
You can verify this using the Jayway JsonPath evaluator.
If this ...
How can I check whether myValue is empty or not?
... means something like: "I only want to return the document if myKey is populated" then the above jsonpath filter should suffice.
The find method in js-data-http appears to have a special case where if item is falsey then it will reject the promise, otherwise it returns item. My problem is that some falsey values (0, null, '') are valid responses from my API.
For example if I ask for a relation that hasn't been set then the API responds with data null wrapped in a jsonapi envelope. This follows the jsonapi spec for fetching empty relationships:
{
"links": {
"self": "/articles/1/relationships/author",
"related": "/articles/1/author"
},
"data": null
}
I'm using the js-data-jsonapi library to help js-data and jsonapi get along. In that library the DeSerializer unwraps the jsonapi envelop. At that point js-data is back in charge and the unwrapped data null is the value for item in the find promise resolve method which causes js-data-http to reject the promise.
Right now I'm taking advantage of a special case in js-data-jsonapi to deserialize null data as an array because in JS Arrays are truthy. But then I must special case the detection for hasOne relations where now an empty array must be re-converted into null.
This seems like an overly complicated way of handling things, is there a better way that I am missing?
My setup uses:
"angular": "1.5.8",
"js-data": "2.9.0",
"js-data-angular": "3.2.1",
"js-data-jsonapi": "0.0.0-alpha.21",
I want to use Fiddler to compose a HTTPRequest to an ASP.Net MVC Controller/Action. However, in this request, I want to be able to pass a JSON object as an object, and not simply as key value pairs which map to the different arguments in the method. I want to be able to test passing a complex type as one argument in the Controller/Action method.
This can be done in JQuery using Json.stringify({{json here}}) which passes the object as an object to MVC, and doesn't parse it into KVPs. Once again, I'm just looking to be able to test the same behavior in Fiddler, if it's possible.
Fiddler Request
The answer to this was simpler than I thought. What Json.stringify does, at it's core, is to wrap the Json string into an object which then becomes one single solitary KVP object, which then gets auto mapped based on the members and values of the Json Object passed and cast into your complex type object argument in your controller/action.
So, all I had to do was wrap the JSON object notation,
{
"FirstName": "Your",
"LastName": "Mom",
"Email": "yourmom#gmail.com",
"FilmAndSiteUpdates": true,
"CompanyUpdates": true
}
into a Json object "instance" so to speak by assigning it to a member by the same name of the method signature, like so...
{
"input": {
"FirstName": "Your",
"LastName": "Mom",
"Email": "yourmom#gmail.com",
"FilmAndSiteUpdates": true,
"CompanyUpdates": true
}
}
...and ASP.NET MVC does the implicit casting for you.