I'm writing a completion extension for VS Code. registerCompletionItemProvider() requires a DocumentSelector selector to specify which documents it works with. I currently have this, which seems to work, but isn't very elegant:
let provider = vscode.languages.registerCompletionItemProvider(
[{ pattern: '**', scheme: 'file' }, { pattern: '**', scheme: 'untitled' }],
{ /* other stuff */ }
);
If I leave scheme off it works as well, but VS Code gives me a guilt-trip warning implying I should keep it. Is there a simpler way to select all documents?
Related
I'm playing with vs code extension development, and I'm trying to create a viewsWelcome element.
content accepts a string with markdown annotations, the following works as expected
"viewsWelcome": [
{
"view": "view-id",
"contents": "[Clone Repository](command:git.clone)"
}
]
However, when trying to replace command:git.clone with command:vscode.open which accepts an uri as parameter, the parameter is not working.
"viewsWelcome": [
{
"view": "view-id",
"contents": "[Open URL](command:vscode.open?[https://foobar.com])"
}
]
I haven't found documents about the syntax, except for some examples here, which is not working as well
Use the following code to generate the correct arguments string:
const args = [
vscode.Uri.parse("https://foobar.com")
];
const encodedArgs = encodeURIComponent(
JSON.stringify(args)
);
console.log(encodedArgs);
// %5B%7B%22%24mid%22%3A1%2C%22path%22%3A%22%2F%22%2C%22scheme%22%3A%22https%22%2C%22authority%22%3A%22foobar.com%22%7D%5D
Then add the encoded arguments to the command: URI:
"viewsWelcome": [
{
"view": "view-id",
"contents": "[Open URL](command:vscode.open?%5B%7B%22%24mid%22%3A1%2C%22path%22%3A%22%2F%22%2C%22scheme%22%3A%22https%22%2C%22authority%22%3A%22foobar.com%22%7D%5D)"
}
]
As you can see it is not sufficient to just pass the URL as a plain string like you did. It has to be the JSON representation of a vscode.Uri.
Additionally, you have to properly URL-encode the resulting JSON before adding it to the command: URI.
Btw, it was the "command:git.stage" example in the VS Code API docs that got me on the right track.
Basically I want to use a formatter function to fill the 3 properties of an sap.m.ObjectStatus (text, state, icon) depending on some static value.
<m:ObjectStatus
text="{
parts: [
{ path: 'currentRoles>STATE_TEXT' },
{ path: 'currentRoles>STATE' },
{ path: 'currentRoles>REFERENCED_ENTRY/SV_RH_ROLE_ACTIVE' },
{ path: 'currentRoles>invalid' },
{ value: 'text' }
],
formatter: '.formatter.Formatter.convertRoleStatus'
}"
...
/>
The strange thing is; if I omit the value part in the XML, the function is called. If it's included, the function gets never called in the first place.
As of the one of the answers to the post Pass Static Value to Formatter Parameters in XML View, passing parameters with value should work if the UI5 version is higher than 1.61. We use 1.71.2.
At other places in code, this works.
How to fix this issue?
Update: The issue is fixed now with commit: 4a9cf89 which will be available in 1.80+.
Now static bindings can be used even without any workarounds like the one mentioned below.
Original answer (workaround):
The issue is now reported in https://github.com/SAP/openui5/issues/2916. Thanks for making us aware of it!
A quick "fix" (I'd say a monkey patch) is to add model: 'myExistingModel' to the static binding info:
parts: [
{ path: 'currentRoles>STATE_TEXT' },
{ path: 'currentRoles>STATE' },
{ path: 'currentRoles>REFERENCED_ENTRY/SV_RH_ROLE_ACTIVE' },
{ path: 'currentRoles>invalid' },
{ value: 'text', model: 'currentRoles' }
],
This fix actually doesn't make sense since static bindings don't have any models, but can be used until the official fix arrives without the need to refactor a lot.
I suspect there is a limitation (possibly a bug):
If you do not use a named model this works for me:
...
??="{ parts : [ {path: 'a'}, {path: 'b'}, {path: 'c'}, {path: 'd'}, {value: 23} ], formatter: '.myFormatter'}"
...
let model = new JSONModel(this.getData());
this.getView().setModel(model);
...
myFormatter: function (a, b, c, d, v) {
console.log(a, b, c, d, v);
},
getData: function(){
return {"testdata": [
{ a: 1, b: "stringB", c: "stringC", d: "stringD"},
]};
}
console output: 1 "stringB" "stringC" "stringD" 23
The moment I name my model this stops working.
For now, if possible, use the default model for your data - not ideal?!
Try (you may have to do some model name trading?!) after assigning the named model as the default (un-named) model:
parts: [
{path: 'STATE_TEXT'},
{path: 'STATE'},
{path: 'REFERENCED_ENTRY/SV_RH_ROLE_ACTIVE'},
{path: 'invalid'},
{value: 'text'}
],
while this gets it to work you may want to raise this with the UI5 Team?
As for now, since changing the binding to a default one like Bernard propsed was not possible without heavy refactoring, I changed my formatter logic a bit in a way such as to create 3 seperat functions (with 4 parameters) that call the orginal convertRoleStatus function, each with different inputs for the fifth parameter, which is mode.
I will report the problem with SAP to hopfully resolve it someday.
Greeting everyone, I have a datatable in my html page that I populated using REST API. I can create new row and also update or delete by selecting a row and clicking the edit or delete button.
But currently I am unable to delete update or delete multiple row at once due to url error,
e.g : PUT http://127.0.0.1:8000/dashboard/content_detail/5,7,9/ 404 (Not Found)
how can I split this this into several separate url with respective id when I update or delete.
e.g :
/dashboard/content_detail/5
/dashboard/content_detail/7
/dashboard/content_detail/9
Below is my code, any help is much appreciated thank you.
idSrc: 'id',
ajax: {
create: {
type: 'POST',
url: content_path,
data: function (content_data) {
var create_data = {};
$.each(content_data.data, function (id, value) {
create_data['name'] = value['name'];
create_data['description'] = value['description'];
create_data['category'] = value['category'];
});
return create_data;
},
success: function () {
content_table.api().ajax.reload();
}
},
edit: {
type: 'PUT',
url: '/dashboard/content_detail/_id_/',
data: function (content_data) {
var updated_data = {};
$.each(content_data.data, function (id, value) {
updated_data['description'] = value['description'];
updated_data['category'] = value['category'];
updated_data['name'] = value['name'];
});
return updated_data;
},
success: function () {
content_table.api().ajax.reload();
}
},
remove: {
type: 'DELETE',
url: '/dashboard/content_detail/_id_/',
data: function (content_data) {
var deleted_data = {};
$.each(content_data.data, function (id, value) {
deleted_data['id'] = id;
});
return deleted_data;
},
success: function () {
content_table.api().ajax.reload();
}
}
},
If you're going to allow the update of a large number of items at once, then PATCH might be your friend:
Looking at the RFC 6902 (which defines the Patch standard), from the client's perspective the API could be called like
PATCH /authors/{authorId}/book
[
{ "op": "replace", "path": "/dashboard/content_detail/5", "value": "test"},
{ "op": "remove", "path": "/dashboard/content_detail", "value": [ "7", "9" ]}
]
From a design perspective you don't want several ids in your url.
I would prefer single calls for each change, thinking in resources you only manipulate one at a time.
In case this is a perfomance issue, I recommend a special url marked with action or something simliar, to make clear this ist not REST.
In HTTP it is not required for information to only exist on a single resource. It is possible to have multiple resources that represent the same underlying data.
It's therefore not out of the question to create a resource that 'represents' a set of other resources that you wish to DELETE or PUT to.
I do agree that it might not be the most desirable. I think we tend to prefer having information only exist in a single part of tree, and I think we like to avoid situations where updating a resource effects a secondary resource's state. However, if you are looking for a strictly RESTful solution to solve this problem, I think it's the right way.
Therefore a url design such as:
/dashboard/content_detail/5,7,9/
Is not necessarily non-RESTful or goes against the HTTP protocol. The fact that you're getting a 404 on that URL currently has to do with your application framework, not the protocol (HTTP) or architecture (REST) of your API.
However, for cases such as these I feel I would personally be inclined to sometimes create a separate POST endpoint that, acting outside of REST like an RPC endpoint. Specifically for these types of batch requests.
Does Moongoose 3.8.8 (the lastest version) support $position (http://docs.mongodb.org/manual/reference/operator/update/position/) operator from MongoDB 2.6.0?
In the following code example the new elements is inserted in the end of the array userActivity.activities:
model:
var userActivity = new schema({
userId: {type:String, required:true, unique:true},
activities: [activity]
});
var activity = new schema({
act: {type: Number, required:true},
});
query:
var activity = { act: 1 };
model.userActivity.update(
{ _id: dbact._id },
{ $push: { activities: {
$each: [ activity ],
$position: 0
}
}
},
function (err, numAffected) {
if (!err) {
// do something
}
});
This actually doesn't matter and never matters for any "framework" implementation and I do not mind explaining why.
Every single "framework" ( such as Mongoose, Mongoid, Doctrine, MongoEngine, etc, etc, etc ) are all basically built upon a basic "driver" implementation that has in most cases been developedby the MongoDB staff themselves. So the basic functionality is always ther even if you need to "delve" down to a level in order to use those "native" methods.
So here would be the native usage example in this case:
List.collection.update(
{},
{ "$push": {
"list": {
"$each": [ 1, 2, 3 ],
"$position": 0 }
}
},function(err,NumAffected) {
console.log("done");
});
Note the "collection" method used from the model, which is getting the "raw" collection details from the driver. So you are using it's method and not some "wrapped" method that may be doing additional processing.
The next and most basic reason is if you cannot find the method and application of the operators that you need the here is a simple fact.
Every single operation as used by the methods in every framework and basic driver method is essentially a call to the "runCommand" method in the basic API. So since that basic call is available everywhere ( in some form or another, because it has to be ), then you can do everything that you find advertised on the MongoDB site with every language implementation on any framework.
But the short call to your particular request is, since this is not actually a method call but is simply part of the BSON arguments as passed in, then of course there is no restriction by a particular language driver to actually use this.
So you can use these new argument without of course updating to the most recent version. But you probably will get some nice methods to do so if you actually do.
Yes, you should be able to use it directly as Mongoose will pass through the update clause:
Model.update(
query, /* match the document */
{ $push:
{ yourArrayField:
{
$each: [ 1, 2, 3 ],
$position: 0
}
}
}, function (err, res) { /* callback */ });
The above would insert the values 1, 2, 3 at the front of the array named yourArrayField.
As it's just a pass-through, you'll need to make sure it works with the server version that you're connecting the client to.
I use 0.6.4. Don't work Collection.update(t.data._id, { $set: { name: e.currentTarget.value}}); Session.set("edit-" + t.data._id, false);.
I'd recommend using jQuery to extract the value: $(e.currentTarget).val(). Also, assuming the person template is rendered from an {{#each people}}, you could probably just do this._id, but it's hard to tell without seeing the templates.
People.update(this._id, { $set: { name: $(e.currentTarget).val()}});
I'd also suggest logging these values to the console before the update to make sure the callback is getting executed and that you are reading the right values.