VSCode JSON language server unhandled method - json

I posted this last week and have made progress since, where I've discovered the packages that VSCode's JSON support is delivered via extensions:
https://github.com/vscode-langservers/vscode-json-languageserver
https://github.com/Microsoft/vscode-json-languageservice
and all the rest. I'm trying to reuse this in an Electron (NodeJS) app. I'm able to fork a process starting the language server and initialize it:
lspProcess = child_process.fork("node_modules/vscode-json-languageserver/out/jsonServerMain.js", [ "--node-ipc" ]);
function initialize() {
send("initialize", {
rootPath: process.cwd(),
processId: process.pid,
capabilities: {
textDocument: true
}
});
}
lspProcess.on('message', function (json) {
console.log(json);
});
and I see that console.log firing and showing it seems to be up correctly.
My thoughts are that I just want to send a textDocument/didChange event as per the LSP:
send('textDocument/didChange', {
textDocument: TextDocument.create('foo://bar/file.json', 'json', 0, JSON.stringify(data))
});
where data is a JSON object representing a file.
When I send that message and other attempts at it I get
error: {code: -32601, message: "Unhandled method textDocument/didChange"}
id: 2
jsonrpc: "2.0"
Any idea what I'm doing wrong here? My main goal is to allow edits through my Electron app and then send the updated JSON to the language server to get schema validation done.
EDIT: I'm even seeing unhandled method initialized when I implement connection.onInitialized() in the jsonServerMain.js.
EDIT2: Update, I figured out where I was going wrong with some of this. initialized and textDocument/didChange are notifications, not requests.

EDIT2: Update, I figured out where I was going wrong with some of this. According to the LSP, initialized and textDocument/didChange are notifications, not requests. Requests have an id field that notifications don't, so when sending a notification, remove the ID field.

Related

Angular resource 404 Not Found

I've read other posts that have similar 404 errors, my problem is that I can correctly query the JSON data, but can't save without getting this error.
I'm using Angular's $resource to interact with a JSON endpoint. I have the resource object returning from a factory as follows:
app.factory('Product', function($resource) {
return $resource('api/products.json', { id: '#id' });
});
My JSON is valid and I can successfully use resource's query() method to return the objects inside of my directive, like this:
var item = Product.query().$promise.then(function(promise) {
console.log(promise) // successfully returns JSON objects
});
However, when I try to save an item that I've updated, using the save() method, I get a 404 Not Found error.
This is the error that I get:
http://localhost:3000/api/products.json/12-34 404 (Not Found)
I know that my file path is correct, because I can return the items to update the view. Why am I getting this error and how can I save an item?
Here is my data structure:
[
{
"id": "12-34",
"name": "Greece",
"path": "/images/athens.png",
"description": ""
},
...
]
By default the $save method use the POST verb, you will need to figure out which HTTP verbs are accepted by your server en order to make an update, most modern api servers accept PATCH or PUT requests for updating data rather than POST.
Then configure your $resource instance to use the proper verb like this :
app.factory('Product', function($resource) {
return $resource('api/products.json', { id: '#id' }, {'update': { method:'PUT' }});
});
check $resource docs for more info.
NOTE: $resource is meant to connect a frontend with a backend server supporting RESTful protocol, unless you are using one to receive data & save it into a file rather than a db.
Otherwise if you are only working with frontend solution where you need to implement $resource and have no server for the moment, then use a fake one, there is many great solutions out there like deployd.
You probably don't implement POST method for urls like /api/products.json/12-34. POST method is requested from angular for saving a new resource. So you need to update your server side application to support it and do the actual saving.
app.factory('Product', function($resource) {
return $resource('api/products.json/:id', { id: '#id' });
});
Try adding "/:id" at the end of the URL string.

PUT requests with Custom Ember-Data REST Adapter

I'm using Ember-Data 1.0.0.Beta-9 and Ember 1.7 to consume a REST API via DreamFactory's REST Platform. (http://www.dreamfactory.com).
I've had to extend the RESTAdapter in order to use DF and I've been able to implement GET and POST requests with no problems. I am now trying to implement model.save() (PUT) requests and am having a serious hiccup.
Calling model.save() sends the PUT request with the correct data to my API endpoint and I get a 200 OK response with a JSON response of { "id": "1" } which is what is supposed to happen. However when I try to access the updated record all of the properties are empty except for ID and the record on the server is not updated. I can take the same JSON string passed in the request, paste it into the DreamFactory Swagger API Docs and it works no problem - response is good and the record is updated on the DB.
I've created a JSBin to show all of the code at http://emberjs.jsbin.com/nagoga/1/edit
Unfortunately I can't have a live example as the servers in question are locked down to only accept requests from our company's public IP range.
DreamFactory provides a live demo of the API in question at
https://dsp-sandman1.cloud.dreamfactory.com/swagger/#!/db/replaceRecordsByIds
OK in the end I discovered that you can customize the DreamFactory response by adding a ?fields=* param to the end of the PUT request. I monkey-patched that into my updateRecord method using the following:
updateRecord: function(store, type, record) {
var data = {};
var serializer = store.serializerFor(type.typeKey);
serializer.serializeIntoHash(data, type, record);
var adapter = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
// hack to make DSP send back the full object
adapter.ajax(adapter.buildURL(type.typeKey) + '?fields=*', "PUT", { data: data }).then(function(json){
// if the request is a success we'll return the same data we passed in
resolve(json);
}, function(reason){
reject(reason.responseJSON);
});
});
}
And poof we haz updates!
DreamFactory has support for tacking several params onto the end of the requests to fully customize the response - at some point I will look to implement this correctly but for the time being I can move forward with my project. Yay!
EmberData is interpreting the response from the server as an empty object with an id of "1" an no other properties in it. You need to return the entire new object back from the server with the changes reflected.

Get real response of ngResource save()

I have the following situation:
I use ngResource to save some data to the mysql database and after the successfull save() I want to log the json response the server sends to me:
Document.save({}, postData, function(response){
console.log(response);
});
This does not result in a simple response, but in something like an object with its own methods. I want some smple output like the response.data after an $http.$get:
{
"docClass":"testets",
"colCount":1,
"columns":null,
"groupid":7,
"id":19,
"lang":"de",
"title":"test",
"version":1409849088,
"workflow":"12234"
}
Greets
Check out this answer
Promise on AngularJS resource save action
So I think in your case you need to do
var document = new Document(postData);
document.$save()
.then(function(res){});
But also from the link I provided
This may very well means that your call to $save would return empty reference. Also then is not available on Resource api before Angular 1.2 as resources are not promise based.

jsonp error with .json extension

I am using jsonp to get an external json file from the cloud. I may be being stupid but if I use this file it throws an error but works if I use a file like http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts
The json also works if I pull it in locally
function AppGuides($scope, $http) {
var url = "http://keystone-project.s3.amazonaws.com/assets/documents/AirFrance.json?callback=JSON_CALLBACK";
$http.jsonp(url)
.success(function(data){
$scope.guidedata = data;
console.log('success');
})
.error(function () {
console.log('error');
});
$scope.ddSelectSelected = {
Label: "Select an Option",
class: "hidden"
};
}
UPDATE WITH FIDDLE
http://jsfiddle.net/ktcle/a4Rc2/953/
After closer inspection and trying the code out myself, I can tell you the error is not in this angular application, but with the server where we try to download the JSON.
A simple GET request to http://keystone-project.s3.amazonaws.com/assets/documents/AirFrance.json?callback=JSON_CALLBACK reveals that the Content-Type of the returned data is application/x-unknown-content-type, when it should be application/json.
The exact error it raises is
Resource interpreted as Script but transferred with MIME type application/x-unknown-content-type
This is a server side issue, caused by whoever implemented it.
If you have access to the server code, you should change the Content-Type of the returned data.
If you do not have access, the best you can do is ask whoever does have access to fix this issue.

json response callback load store extjs

I have a JSON store that load data from a PHP script. This script call a Web Service and sometimes it get some errors and I need to capture them and show them in my app.
In my script I print this line when I get an error:
echo '{"success": "false", "error": "'.$res->state->Description.'"}';
In my app I have this code to load the store
targheStore.load({
params: { targa: searchForm.getValues().targa },
callback: function(records, operation, success) {
Ext.getBody().dom.style.cursor = "default";
if(!success){
$("#message2").slideDown('fast');
setTimeout(function() {
$("#message2").slideUp('medium')
}, 2700);
}
}
});
The jQuery code is to show a message "No record found" from the top, but I want to show the error message that I receive from json.
Inside of the operation argument is a request and response object. Use the response object as you would any Ajax response should allow you to handle your messages the way you'd like.
I suggest declaring a globally available handler for processing operation to look for JSON.parse(response.responseText).hasOwnProperty("error") and doing your custom operation in that way.
If you're not using JSONP for communication you can stuff your message in the raw text returned from an HTTP error code (400+) and the {error:} handler in your ajax would be the best way to route errors.