Here's my main.js
require('sdk/request').Request({
url:'https://google.com'
,onComplete:function(response){
console.log('response',response)
}
}).get()
which gives me
console.log: extension: response constructor {}
At first I thought it was a permissions thing, but I whitelisted google and still no response
"permissions": {
"private-browsing": true
,"cross-domain-content":["https://google.com"]
}
I'm using FF31
Turns out the object wasn't actually empty, it just appeared empty in the console. When I console.log(response.text) I get the results I expect. This is probably b/c text,json, etc are prototypes of the object and the console ignores prototypes.
Related
I have been working to create an API which programatically creates/updates work item in Azure Devops. I have been able to create a work item and populate almost all fields. I have problem with setting the state.
When I am creating a POST request to Azure Devops rest api with any state name like "Active", "Closed", "Rejected", it throws a 400 Bad Request error.
I don't know if I am missing anything or if there something wrong with the way I am trying to set the value.
{
"op" : "add",
"path": "/fields/System.State",
"value"="Active",
}
I have found the solution to this problem and hence I am answering it here.
I was getting a 400 Bad Request error whenever I tried Creating an Item and Setting the state in the same call. I debugged the code and caught the exception. I found out that, there are some validation rules for some of the fields. State is one of them.
The rule for System.State field is, whenever a Work Item is created it takes its configured default value. ( In my case it was "Proposed", in your case it could be "New"). If you try altering the value at the time of work item creation, it throws a 400 Bad Request.
What should I do if I have to Create a Work Item with a specific State?
As of now, the solution that I have found out is to make two calls. One for Work Item Creation and another for Changing the state of the work item to desired state.
CreateWorkItem()
{
var result = await _client.Post(url, jsonData);
var result2 = await _client.Put(result.id, jsonData); // or maybe just the state
return Ok(result2);
}
Check the example here: Update a field
You have to use "value":"Active" in the request body.
[
{
"op" : "add",
"path": "/fields/System.State",
"value": "Active"
}
]
I'm building an app that needs to make a GET request to the API endpoint https://thecountedapi.com/api/counted using the Siesta framework. The endpoint returns a JSON array, just like an endpoint like https://api.github.com/users/ebelinski/repos, which is used in the Siesta example Github Browser. As a result, I'm trying to make my app use Siesta in the say way that one does. I create a service:
let API = Service(baseURL: "https://thecountedapi.com/api")
Then a transformer for my endpoint in application:didFinishLaunchingWithOptions:
API.configureTransformer("/counted") {
($0.content as JSON).arrayValue.map(Incident.init)
}
Where Incident is a struct with an initializer that takes in a JSON object.
Then in my view controller, I create a resource:
let resource = API.resource("/counted")
and in viewDidLoad:
resource.addObserver(self)
and in viewWillAppear:
resource.loadIfNeeded()
Then I have the following function in my VC to listen to changes:
func resourceChanged(resource: Resource, event: ResourceEvent) {
print(resource.jsonArray)
if let error = resource.latestError {
print(error.userMessage)
return
}
if let content: [Incident] = resource.typedContent() {
print("content exists")
incidents = content
}
print(incidents.count)
}
But when I run my app, I get mixed results. print(resource.jsonArray) just prints [], I have an error message Cannot parse server response, and if I set Siesta.enabledLogCategories = LogCategory.detailed, I can see the error mesage [Siesta:StateChanges] Siesta.Resource(https://thecountedapi.com/api/counted)[] received error: Error(userMessage: "Cannot parse server response", httpStatusCode: nil, entity: nil, cause: Optional(Siesta.Error.Cause.WrongTypeInTranformerPipeline(expectedType: "JSON", actualType: "__NSCFArray", transformer: Siesta.ResponseContentTransformer<SwiftyJSON.JSON, Swift.Array<TheCountedViewer.Incident….
If I comment out the whole transformer, I have some success in that print(resource.jsonArray) prints out the correct array from the endpoint. So my transformer must be wrong in some way, but I think I'm using basically the same transformer as in Github Browser:
service.configureTransformer("/users/*/repos") {
($0.content as JSON).arrayValue.map(Repository.init)
}
Am I missing something?
The key clue to your problem is buried in that (perhaps not ideally helfpul) log message:
Siesta.Error.Cause.WrongTypeInTranformerPipeline
expectedType: "JSON"
actualType: "__NSCFArray"
It’s saying that your transformer expected an input type of JSON, which makes sense — you said as much with ($0.content as JSON). However, it got the type __NSCFArray, which is the secret internal backing type for NSArray. In other words, it expected a SwiftyJSON value, but it got the raw output of NSJSONSerialization instead.
Why? The GithubBrowser project includes an NSDict/NSArray → SwiftyJSON transformer which it configures in the parsing stage. The model transformers in that project all depend on it.
To use SwiftyJSON in the same way in your project, you’ll need to include that transformer from the example project in yours:
private let SwiftyJSONTransformer =
ResponseContentTransformer
{ JSON($0.content as AnyObject) }
And then when setting up your service:
service.configure {
$0.config.pipeline[.parsing].add(SwiftyJSONTransformer, contentTypes: ["*/json"])
}
(Note that you might want to create the ResponseContentTransformer with transformErrors: true if you are interested in errors.)
An alternative way to use SwiftyJSON, which is not quite as pretty but requires less setup, is to manually wrap things in JSON in each individual response transformer:
service.configureTransformer("/users/*/repos") {
JSON($0.content as AnyObject).arrayValue.map(Incident.init)
}
event.respondWith(caches.match(event.request).then(function (response) {
if (response) {
return response;
}
//return fetch(event.reuqest, { credentials: 'include' });
//event.respondWith(fetch(event.request, { credentials: 'include' }));
}));
This is a common code for handling request via serviceworkers , if the url is in cache then return cache response or fetch it from server .
But my doubt is regarding the 2 commented lines , we need to use one of them for fetching the response .
My doubt is, when i use event.respondWith(fetch(event.request, { credentials: 'include' for fetching a page , i get the following error
DOMException: Failed to execute 'respondWith' on 'FetchEvent': The fetch event has already been responded to.
But the page is finally rendered , definitely browser is finally fetching the response , but when i use sam for fetching an image , i get the same error and on top of that the image is not fetched .
if i use the second option that return fetch(event.reuqest, { credentials: 'include' }); , then it works fine for both image as well as page.
I am not able to figure out what is the reason of that error , and also why it is behaving differently for file and page .
My another doubt is , do i actually need the credential parameter here ,i added it because most of the implementations i saw in web have used it,but what i have observed is that the request object already has a credential property with it , now it is not always
include
sometime it is
same-origin
too.
So could it happen that i am actually overriding the actual credential value by adding it .If that is not the case , then there is no difference in including it or not.It does not matter .
But if it is other way around , then we should not overwrite the credential value, which can have bad side effects.
You already have a call to event.respondWith, you don't need to call it twice.
Your first call is going to use the promise returned by:
caches.match(event.request).then(function(response) {
if (response) {
return response;
}
return fetch(event.reuqest, { credentials: 'include' });
})
This promise resolves to:
response, if the request is in the cache;
the promise returned by the call to fetch, otherwise.
The promise returned by fetch will resolve to a response, which is then going to be used by respondWith.
I'm struggling to debug this error because, although it's consistently reported, the app's behavior is as intended. Would appreciate pointers as to what it means and how I could go about debugging its source.
Apologies for being vague but, since I'm getting the desired result, I'm unsure what other information to provide.
UPDATE
I've created a repro of this issue and attempted to focus the code on the problem. The error is thrown consistently even though the database is updated correctly. There's a single saveChanges in the code and it uses the save functionality from the dataservice.js in the Breeze Todo sample. SaveOptions.allowConcurrentSaves is false.
Entirely at a loss to explain it and have looked through my EF code to see whether I'm making an obvious mistake but can't see it. The bundle sent to the WebAPI SaveChanges method looks correct (correctly populated with IDs etc.) too.
https://github.com/DazWilkin/BreezeJS.ScoreIssue
UPDATE 6th February
The issue remains unresolved by Wade's helpful answer. Unfortunately, unless I can understand what it is I'm doing wrong or learn that this is a bug, I'm going to have to abandon the use of Breeze in this project and revert to crappy, plain old AJAX calls.
It would appear that the issue revolves around the server returning a zeroed GUID when saving changes. The method returns no errors. I would be thrilled to learn that this is a bug in my entity model but I'm doubtful.
Here's the failure:
breeze.debug.js: 11954
var ix = this._indexMap[tempValue];
if (ix === undefined) {
throw new Error("Internal Error in key fixup - unable to locate entity");
}
When the code reaches this point, the value of this._indexMap is correct and is:
{"bcb6e670-00fc-469d-8531-5767f40bf3c1":0}
BUT the value of tempValue (as returned from the Web API call by the server) is wrong:
00000000-0000-0000-0000-000000000000
The realValue is correct and is:
1093b975-7686-4621-8336-77c38ed36de0
Backing up the stack. Here are the results from the AJAX call, breeze.debug.js: 12574. See that the tempValue is zeroed on return from the server/WebAPI call. The realValue is correct. This is what the database contains. The row is added to the table without problem.
"KeyMappings": [
{
"$id": "4",
"$type": "Breeze.WebApi.KeyMapping, Breeze.WebApi",
"EntityTypeName": "...Score",
"TempValue": "51877f5b-811f-4260-bd5b-cf9965159597",
"RealValue": "92b73b8a-8b33-45cd-9822-ca7c0c5d5d9a"
},
{
"$id": "5",
"$type": "Breeze.WebApi.KeyMapping, Breeze.WebApi",
"EntityTypeName": "...PropertyValue",
"TempValue": "00000000-0000-0000-0000-000000000000",
"RealValue": "1093b975-7686-4621-8336-77c38ed36de0"
}
],
Verified against what's received serverside in saveBundle. NB the IDs of both entities received at the server have valid GUID IDs.
"entities": [
{
"ID": "51877f5b-811f-4260-bd5b-cf9965159597",
...
"entityAspect": {
"entityTypeName": "Score:...",
"entityState": "Added",
"originalValuesMap": {},
"autoGeneratedKey": {
"propertyName": "ID",
"autoGeneratedKeyType": "Identity"
}
}
},
{
"ID": "bcb6e670-00fc-469d-8531-5767f40bf3c1",
...
"entityAspect": {
"entityTypeName": "PropertyValue:...",
"entityState": "Added",
"originalValuesMap": {},
"autoGeneratedKey": {
"propertyName": "ID",
"autoGeneratedKeyType": "Identity"
}
}
}
],
Unsurprisingly, the values sent to the server by the AJAX call that are created in breeze.debug.js: 10494 saveBundleStringified are correct and the same as those received by the server (won't reproduce but I assure you they are).
And, from my code, when the saveChanges is called,
manager.getChanges().length == 2
manager.getChanges()[0].ID() == "51877f5b-811f-4260-bd5b-cf9965159597" (Score)
manager.getChanges()[1].ID() == "bcb6e670-00fc-469d-8531-5767f40bf3c1" (PropertyValue)
and, as expected, these match the (temp) values of the entities' IDs during saveChanges, received by the server...
What am I doing wrong?? If I had hair, I'd be tearing it out!
I've solved it.
My inconsistently applied (!) convention is to make the setters internal/private on code first types. I say inconsistently because, after feeling that I'd exhausted all possibilities, I discovered that the PropertyValue type, i.e. the one originating the error, had an internal set.
Having removed this and rebuilt the solution, the problem is solved!
So:
public Guid ID { get; internal set; }
Should be:
public Guid ID { get; set; }
Update Jan 27:
Based on your comments to Sergey's answer, you may have been trying to do something with the changed entities before the save operation completed.
Those entities remain in their changed state ... often with temporary primary and foreign keys ... until the server reports a successful save.
You probably shouldn't touch them until the save succeeds. As Sergey observes, you should locate your post-save processing in the save success callback.
return manager.saveChanges()
.then(saveSucceeded)
.fail(saveFailed);
You should not wrap the saveChanges call in a jQuery Deferred. That is a waste of time and complexity. The EntityManager.saveChanges method returns a promise that your caller can consume. The view models can add their own success and failure callbacks
dataservice.saveChanges()
.then(hooray)
.fail(sadTrombone);
Concurrent saves
I noticed in your code that you are guarding against illegal concurrent saves using the time-delay approach you found in the Todo sample.
That approach is really only suitable for the demo. It won't work at all for you if your view models need to perform some tasks when the save succeeds. It won't work because the dataservice can't return a promise to the view models with the time-delay approach.
If you need non-blocking saves, check out the "Save Queuing" plugin described in the "Concurrent Saves" topic under the "Cool Breezes" section.
Creating entities succinctly
While looking at your code, I couldn't help noticing that your entity factory methods in scoreissue.1.0.ts were a bit verbose. What you have written as:
export function Business(manager, o: IBusiness) {
var business = manager.metadataStore.getEntityType("Business").createEntity();
business.ID(breeze.core.getUuid());
business.Name(o.name);
manager.addEntity(business);
return business;
}
could be as simple as:
export function Business(manager, o: IBusiness) {
return manager.createEntity("Business", {
ID: breeze.core.getUuid(),
Name: o.name,
});
}
The EntityManager.createEntity shortcut is new since you wrote this code so don't feel bad about having missed it.
Original answer:
[Wrong direction. Preserved to make sense of DazWilkin comment that the problem is on the client.]
Where is this being generated? On the server? If so, you can subclass EFContextProvider and override SaveChangesCore. Call the base.SaveChangesCore and put a try/catch around it. Inspect the saveMap argument. The EFContextProvider is open source; I'd start digging here.
This error can occur with multiple simultaneous save requests pending at the same time both involving key generation. Does this error only occur during a save? If so try setting your SaveOptions.allowConcurrentSaves to false. If this causes a different error, (a concurrent save error) to occur then your problem definitely has to do with concurrent saves.
Hope this helps.
I have the same problem, and I've solved it with help of jQuery deferred object. My dataservice save method now looks as follows:
saveChanges = function () {
var def = $.Deferred();
if (manager.hasChanges()) {
manager.saveChanges()
.then(function () { def.resolve() })
.fail(function (error) {
handleSaveError(error);
def.reject();
});
} else {
logger.info("Nothing to save");
def.resolve();
};
return def.promise();
};
And I call it from my view models also using jQuery deferred object:
$.when(dataservice.saveChanges())
.done(function () {
...some actions
})
I am facing a problem with getting a response in fetch function of backbone.js. I am using Backbone.js with rails.
$(document).ready(function(){
window.projectPerformanceReport.fetch({
success: function(e) {
$("#loading").hide();
window.questionListView = new QuestionListView;
window.questionListView.render();
window.headerView = new HeaderView;
window.headerView.render();
},
error: function() {
alert("Error");
}
});
});
There is already a URL set for the fetch method and it does make a request to online server which returns a JSON object. I checked by hitting that request independently in new tab and it worked fine. Also the JSON object returned is valid. But when i run this page i always get popup of 'Error'?
Any help would be great.
Thanks
Okay
I got what was the issue..... The thing that was happening was, The Java_Servlet which i was calling to get the JSON object was returning the data in text format instead of JSON... (But it was a valid JSON string)... and while calling the ajax method i had set the type as 'json' so it was failing.
Thanks to everyone who read my question and thought for a solution.
But one strange thing which i observed was, same code was working in production and not in my local machine??? Does anyone have some idea on why it could be behaving like that..???
Thanks :) Now i can sleep properly!!