Couchbase Java API and javascript view not returning value for a specific Key - javascript

I am using couchbase API in java
View view = client.getView("dev_1", "view1");
Query query = new Query();
query.setIncludeDocs(true);
query.setKey(this.Key);
ViewResponse res=client.query(view, query);
for(ViewRow row: res)
{
// Print out some infos about the document
a=a+" "+row.getKey()+" : "+row.getValue()+"<br/>";
}
return a;
and the java script view in couchbase
function (doc,meta) {
emit(meta.id,doc);
}
So, when I remove the statement query.setkey(this.Key) it works returns me all the tables, what am I missing here .. How can I change the function to refect only the table name mentioned in the key

Change the map function like this:
function (doc,meta) {
emit(doc.table,null);
}
it is good practice not to emit the entire document like:
emit(doc.table, doc)
NB: This is surprisingly important:
i have tried using setKey("key") so many times from Java projects and setting the key using CouchBase Console 3.0.1's Filter Result dialog, but nothing get returned.
One day, i used setInclusiveEnd and it worked. i checked the setInclusiveEnd checkbox in CouchBase Console 3.0.1's Filter Result dialog and i got json output.
query.setKey("whatEverKey");
query.setInclusiveEnd(true);
i hope this will be helpful to others having the same issue. if anyone finds another way out, please feel free to add a comment about it.
i don't know why their documentation does not specify this.
EXTRA
If your json is derived from an entity class in a Java Project, make sure to include an if statement to test the json field for the entity class name to enclose you emit statement. This will avoid the key being emitted as null:
if(doc._class == "path.to.Entity") {
emit(doc.table, null);
}

Related

Ready ViewBag values from controller?

In my controller I have the following ViewBag which has hard coded values for a drop down list
public ActionResult Order(string id, string printRequest)
{
this.ViewBag.PartialReasons = new List<string>() {" ", "Insufficient stock", "Suspended", "Retired", "Ordered Incorrectly", "Unable to deliver" };
}
I want to do is that once from a drop down the value "Unable to deliver" is selected, then have a alert POP up with "HELLO EVERYONE" appear, then user should be able to click on and save, my existing save function onclick is below,
in a nutshell just want to read a value from a controller viewbag.
$('.pcss-save').click(function() {
if (CheckSerialNumbersForQuantity()) {
if (CheckReasons()) { //If Ordered incrrectly
$('#genericmodal').find(".pcss-submit-genericmodal").unbind("click");
$('#genericmodal').find(".modal-title").html("Confirmation");
$('#genericmodal').find(".modal-body").html("This order will be Cancelled");
$('#genericmodal').modal('show');
$('#genericmodal').find(".pcss-submit-genericmodal").click(function() {
$("#orderform").submit();
});
} else {
$("#orderform").submit();
}
}
});
First some questions:
How are you loading the Viewbag values into the drop-down?
Are you using Razor views?
it seems you are asking multiple questions, so I'm going to try and hit each.
Typically drop downs are key-value pairs. With Razor views you can use:
#Html.DropDownList("reasonListID", new SelectList(ViewBag.PartialReasons, "reasonCode", "reasonName"))
This assumes that the viewbag object is a list of object with two properties reasonCode and reasonName.
Pure lists of strings are not really used to drive logic, you want to codify your potential values to give yourself clear and easy comparisons. In this way, you can simply look at reasonCode and not have to code for comparing your select value to "Some long string that may not have a lot of meaning in code" e.g. this would probably be in your CheckReasons() function.
if CheckReasons() == "UD") {
showModal( "HELLO EVERYONE");
}
is easier than
if CheckReasons() == "Unable to deliver") {
showModal("HELLO EVERYONE");
}
As far as popping the modal, it looks like you are using jquery, so take a look that this answered question: MVC3 Razor and Modal popup
In your view, you should be able to call your ViewBag directly by using #ViewBag.PartialReasons and when the Razor engine renders the script, it will use those values in #ViewBag.PartialReasons.
You might want to do something like this.
$('#yourDropDownID').on('change', function(){
if(CheckReasons()){
var genericModal = $('#genericmodal'); //Avoids rescanning the dom.
genericModal.find(".pcss-submit-genericmodal").unbind("click");
genericModal.find(".modal-title").html("Confirmation");
genericModal.find(".modal-body").html("This order will be Cancelled");
genericModal.modal('show');
genericModal.find(".pcss-submit-genericmodal").click(function() {
$("#orderform").submit();
}
});
And your check reasons might be something like this. This is kind of open to interpretation.
function CheckReasons(){
var myReason = #String.Join(ViewBag.PartialReasons.ToArray());
//loop and figure it out if your reason is selected and return true or false
}
This was all written off the top of my head, so it may need a little tweaking, but this should get you started with what you're looking to do.
UPDATE
You cannot access the ViewBag within your browser as it only exists server side. You need to render out a script that accomplishes what you desire on the server using ViewBag. The Razor engine will fill in the output from the C# code.

Breeze EntityManager.executeQuery with expand - httpResponse data does not match result data?

I'm working on a web app that uses Breeze and Knockout. I have the following function:
function getArticle(id, articleObservable) {
var query = EntityQuery.from('KbArticles')
.where("articleId", "==", id)
.expand("KbArticleType, KbSubject, KbArticleTags");
return manager.executeQuery(query)
.then(querySucceeded)
.fail(queryFailed);
function querySucceeded(data) {
if (articleObservable) {
articleObservable(data.results[0]);
}
log('Retrieved [Article] from remote data source', data.results.length, true);
}
}
A 1 to many relationship exists between the KbArticles entity and the KbArticleTags entity. The goal of this function is to fetch a specific article and the list of tags associated with the article. The function executes successfully (and I DO get data for the other 2 expanded entities - they are 1 to 1), however, I get an empty array for the KbArticleTags in data.results. Interestingly, the tags are populated in data.httpResponse:
So, it appears that the data is coming over the wire, but it's not making it to the results in the querySucceeded function. I tried to step through the breeze code to determine how the httpResponse is mapped to the result, but got lost fairly quickly (I'm a javascript newb). Does anyone have any troubleshooting tips for figuring out why the expanded entity doesn't show in the results, but is returned in the httpResponse? Or am I trying to do something that isn't supported?
Ok, so for whatever reason (I probably deleted it one day while testing and didn't add it back), the navigation property (in my Entity Framework diagram) was missing on the KbArticleTag entity:
All I had to do was add that back and everything is working as expected.

Xstream generated json response for List<Object>

I am using Xstream to generate JSON for my application.I want to use JSON for ajax support. When i try
xstream.alias(classAlias, jsonModel.getClass()); //Note classAlias="records"
responseStream.println(xstream.toXML(jsonModel));
where jsonModel is actually a List of entity objects.Entity class name is Person which is in "beans" package so full qualified name would be beans.Person. OK
Person class has properties like id,name,age etc.
Generated JSON is
{"records":[{"beans.Person":[{"id":21,"name":"Name21","username":"Username21","password":"password21","age":41,"sex":true},{"id":22,"name":"Name22","username":"Username22","password":"password22","age":42,"sex":true},{"id":23,"name":"Name23","username":"Username23","password":"password23","age":43,"sex":true},{"id":24,"name":"Name24","username":"Username24","password":"password24","age":44,"sex":true},{"id":25,"name":"Name25","username":"Username25","password":"password25","age":45,"sex":true},{"id":26,"name":"Name26","username":"Username26","password":"password26","age":46,"sex":true},{"id":27,"name":"Name27","username":"Username27","password":"password27","age":47,"sex":true},{"id":28,"name":"Name28","username":"Username28","password":"password28","age":48,"sex":true},{"id":29,"name":"Name29","username":"Username29","password":"password29","age":49,"sex":true},{"id":30,"name":"Name30","username":"Username30","password":"password30","age":50,"sex":true}]}]}
I used $.getJSON of jquery to get this response on button click event. I checked the status which is "success" every time so this is working well.Problem occurs when i try to access first records i.e. person's information like id,username etc.
I write statements in Javascript as
<script>
$(document).ready(function() {
$("input").click(function(){
$.getJSON("http://mylocalhost:8080/Paging/paging/records?page=3",function(data,status){
alert(status);
alert(data.records[0].beans.Person[0].id);
});
});
});
</script>
First alert works but second doesn't.
Then javascript stops working as it does whenever encounters an error.What i can guess is that in records array Person object is followed by package name.This could be the reason because browser may look for beans object in records array which is not there because beans.Person is a single, atomic name in this case as shown in above. But not sure?
If this is actually problem then how can i stop/control XStream to name an object's name as just classname(person) instead of package.classname(beans.person) as it is being named by default.
or If everything is OK in produced JSON object then why can't i see the expected result? Why simple second alert statement is not working.
I got the answer I was to use
alert(data.records[0]["beans.Person"][0].id);
instead of
alert(data.records[0].beans.Person[0].id);
A useful link
http://www.javascripttoolbox.com/bestpractices/#squarebracket

Databinding to Windows 8 ListView

I'm having massive problems with databinding to a ListView in a Windows 8 app using Javascript.
Inside the "activated" event on default.js I have written some code to get some data from a web service and push it into an array. This bit works OK and the array is populated.
The problem I have is that the app won't recognise the data. I have this code in a page called inspections.html:
data-win-options="{itemTemplate: select('#imageTextListCollectionTemplate'),
itemDataSource: dataList.dataSource,
layout: {type: WinJS.UI.ListLayout}}
and then in the "activated" event I declare:
var dataList = new Array();
and push the data from the web service into this array. But at runtime I get an error that says something along the lines of "can't find dataSource on undefined dataList".
I've done some of the examples on the MS website and in one of them it creates a dummy dataset and references it from a namespace. I kinda think that what I'm missing here is a namespace too but I don't know what the namespace for default.js is. Or maybe I'm wrong and it's something totally different.
Please help - this is so fundamental (and should be easy) but I can't get my head around it.
Do you want to create datalist in HTML or javascript?
It seems you want to create it from JavaScript. Assuming that you have already pushed your data into array from your webservice, you only need to call:
var dataList = new WinJS.Binding.List(array);
now accessing dataList.dataSource is perfectly valid.
Also, to create the datalist you don't always need an array. You could probably start with an empty list and then keep inserting data directly into the data list from web services, like:
var dataList = new WinJS.Binding.List([]);
dataList.push(value1);
dataList.push(value2);
...
Hope it helps. Let me know if you have any more questions.
If you are getting troubled by assigning datasource in HTML side
Prefer js side like
var list = new WinJS.Binding.List(array here);
listView.itemDataSource = list.dataSource;
by using this you can easily go through the data which you are binding to ListView.

JQuery Autocomplete GET & JSON array data security concerns

I am learning JQuery with a MVC3 book. I find that Json data is really easy to use, but it may not be safe.
Consider the scenario, say, I got a CRM with senstive customer infomation. Ajax returns Json array as search results. The search textbox ajax autocomplete also return Json array of senstive keywords from database. etc...They all use GET method.
However, it is said that GET method has vulnerabilities when passing around Json array data:
http://haacked.com/archive/2009/06/25/json-hijacking.aspx
http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
How do you JQuery experts out there go about fixing this issue? Please help.
--- EDIT: ---
#Gren. Awesome. Thank you. Based on your tips, here is what I figured out.
The normal autocomplete returning json array
and a mod one with a json object wrapping the array
Here is the code, assuming we got a global List named txtlst in the controller.cs...
// normal one
public JsonResult AutoCompleteHelper1(string term) {
//if (!Request.IsAjaxRequest()) return null;
var lst = txtlst.Where(s => s.StartsWith(term)).ToList();
var res = lst.Select(x => new { value = x }).ToList();
return Json(res, JsonRequestBehavior.AllowGet);
}
//mod one
public JsonResult AutoCompleteHelper2(string term) {
//if (!Request.IsAjaxRequest()) return null;
var lst = txtlst.Where(s => s.StartsWith(term)).ToList();
var res = lst.Select(x => new { value = x }).ToList();
return Json(new { wrapper= res, name="wrapper" }, JsonRequestBehavior.AllowGet);
}
}
and then in the .cshtml file...
<p>Auto Complete Example</p>
<input type="text" name="q" id="MyInput1" data-autocomplete-source="#Url.Action("AutoCompleteHelper1", "Home")"/>
<input type="text" name="q" id="MyInput2" data-autocomplete-source="#Url.Action("AutoCompleteHelper2", "Home")" />
and then in the .js file...
$(document).ready(function () {
// normal autocomplete
$("#MyInput1").autocomplete({ source: $("#MyInput1").attr("data-autocomplete-source") });
// mod autocomplete with a wrap
$("#MyInput2").autocomplete({
source: function (req, add) {
$.getJSON($("#MyInput2").attr("data-autocomplete-source"), req, function (data) {
var suggestions = [];
$.each(data.wrapper, function (i, o) {
suggestions.push(o.value);
});
add(suggestions);
});
}
});
});
--- EDIT 2: ---
Please ignore those comments that are telling me to use POST. They
are not reading the blog links or do not understand the issue.
The other option is to wrap your JSON Arrays within JSON objects. The article and comments in it answered this question.
Edit:
From the article:
The fact that this is a JSON array is important. It turns out that a script that contains a JSON array is a valid JavaScript script and can thus be executed. A script that just contains a JSON object is not a valid JavaScript file.
If you wrap your json array in an object {"myJsonArray":[{"name":"sensitive"},{"name":"data"}]} the HTML script tag would not be able to execute.
Security of an Ajax/JSONP/JSON call is the same exact thing as the security of an http call since Ajax requests are http requests. Nothing changes in how you handle it. You make sure the user is logged in and can access the information.
If you are worried about data being cached, use Post or set the proper no caching headers with the backend.
EDIT:
Things you can do to prevent JOSN from being read is the infinite loop trick. Stick an infinte loop in front of the call, means your Ajax call will have to strip this before using it.
You can use keys, third party site would not have the keys needed to validate the request.
You can check referrers.

Categories

Resources