The javascript one seems pretty simple, just localStorage.clear().
Is there anything similar to that for the backbone localstorage, and if not, can someone point me in the right direction on how to do it.
I was thinking about doing something like this:
localStorage.each(localStorage.delete(this))
except this wouldn't point to that element would it?
Few ways you can do this from the Collection, but whichever way you choose, you have to call destroy on each model, which will run sync and destroy it on both the client-side and server-side (which localStorage is acting as).
collection.each(function(model) {
model.destroy();
}
)
Update
Per comments, doesn't look like this works anymore. Since this is still marked as the answer, including answer that should work below, per skcin7.
while ((model=collection.shift()))
{ model.destroy();
}
I know this kind of feels like grave digging, but i've been looking for a solution to this for a while now and none of the above snippets seemed to work for me. I always ended up having the size of the collection decreased by half, no matter how i tried it.
So after a decent amount of fiddling, i came up with this:
var length = collection.length;
for (var i = 0; i < length; i++) {
collection.at(0).destroy();
}
Backbone is removing items "on the fly", so if you have 40 items you won't be able to delete the 21. item because there are only 20 items left. Strangely enough this also seems to affect the collection.each() function which really seems like a bug to me..
Just iterating over the collection and calling destroy on each element is not save in any case.
The reason is iterating over collection modified at the same time can produce unexpected results.
It is better to first clone the collection and iterate over this clone. Checkout this.each not iterating through collection correctly for further details.
Example:
_.chain(Todos.models).clone().each(function(model){
console.log('deleting model ' + model.id);
model.destroy();
});
If you don't want to do this programmatically, you can always open up Developer Mode (F12), navigate to the Resources tab, select "Local Storage" from the left pane and delete the records.
Update: In the newer versions of Chrome, the Resources tab has been replaced with the Application tab.
// dc was so close!
let model;
while ( model = collection.at(0) ) {
model.destroy(); // removes model from server and collection
}
Related
I'm trying to sort some data returned by a query in GraphQl. I'm running a Meteor/React/Apollo/Graphql stack, and this line allows me to obtain all the data in my database in a resolver resolvers.js : return database.find({}) I would like to sort it server-side by the "name" field and according to the docs and everything else I've been able to find online so far, return database.find({}).sort({name:1}) should have cut it, but it's not actually returning anything and I can't seem to figure out why, nothing shows up in my console and no errors are being thrown, and hence I believe it's just null or empty.
In my Robo3T console I can run database.find({}).sort({name:1}) and I can see the data actually being sorted. According to the docs I thought it may have been due to the Node implementation, and so I tried sort([["name",1]]) but that did not work either, and I'm not quite sure how else to go about this.
If there is no way to do this - should I just rely on client-side sorting? It's not many entries, < 100, and I think I should just sort it in the database itself because I never need the unsorted data and it's likely not even going to change much.
I would like to ask this regardless though, even if just sorting it once in my database is enough for this specific situation, how would I otherwise go about sorting data in a resolver, because I would need to do this in other instances?
Thanks!
EDIT - This is what I have:
export default {
Query: {
test_query(obj, args, context) {
// Bottom line is output
console.log("test1");
console.log(Database.find({}).sort({name:1}));
// Bottom line is not output
console.log("test2");
return Database.find({});
},
}
EDIT2: My database is defined as Database = new Mongo.Collection("db_name")
I believe you are looking at the wrong documentation. If this is indeed meteor, then Database is presumably a meteor collection, not a raw mongo collection. The interface on meteor collections is slightly different. In your case, I think you want:
Database.find({}, {sort: {name: 1}}).fetch();
.find() returns a cursor:
http://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html#find
This works for Meteor pubsub, but not for GraphQL/Apollo. Try .find().toArray():
http://mongodb.github.io/node-mongodb-native/3.6/api/Cursor.html#toArray
I am using VMWare Clarity datagrid with single selection.
Behind the scene, I am receiving updated data and randomly, the selected row is no more selected.
I found those links where they seemed to have the same issue and looks like it is fixed in 0.12.2, but I don't see that from side:
https://github.com/vmware/clarity/issues/484
https://github.com/vmware/clarity/issues/2342
Here my code
html
<clr-datagrid [clDgRowSelection]="true" [(clrDgSingleSelected)]="selectedUnit">
...
<clr-dg-row *clrDgItems="let unit of units" [clrDgItem]="unit" (click)="backupSelectedUnit(unit)">
...
</clr-dg-row>
</clr-datagrid>
JS
myfunc() {
this.units = this.getUpdatedUnits();
}
Thanks in advance
You are missing the trackBy on *clrDgItems. Whenever you are dealing with objects you receive from the server, you really want to make sure you are using trackBy to help Angular (and thus Clarity) know how to compare your objects. Otherwise the only comparison Angular can perform is reference equality, which isn't preserved when you keep getting updated objects from the server. Here is the official documentation for it, and you can find a maybe more readable explanation in the template syntax docs.
*clrDgItems supports the same trackBy option as *ngFor, so you can just write:
<clr-dg-row *clrDgItems="let unit of units; trackBy: trackById" ...>
where trackById is a function you add to your component that looks like this:
trackById = (index, unit) => unit.id
I'm assuming here that the objects you receive from the server have an id, but you can use any other way to identify them depending on your specific use case.
I am working on a project based on CKAN, and I am required to list in a page all the datasets that have the state "active" and "draft". When you go to the datasets page, you can only see the ones that have the state marked as "active", but not "draft".
If I use the API (call the package_list() method) or REST calls (http://localhost/api/3/action/package_list), CKAN only returns "active" datasets, but not "drafts". I double and triple checked the documentation, and apparently one cannot lists the datasets by their state.
Does anybody have a clue on how to do this? Has anybody done this already?
Thanks!
If nothing else, you could write an extension to do this. The database call itself will be pretty simple:
SELECT id,title,name FROM package WHERE state='active' OR state='draft';
I managed to modify CKAN core to list the datasets that do not have the state "draft" or "deleted", and it works, but I do no want to touch CKAN's core, I want to do this using a plugin, so the normal thing to do is to implement plugins.IActions and override the package_list method with a custom one. I have already written my own extension to try to modify CKAN behavior on method package_list(), but I can't seem to figure it out how to make it work.
Here is my code:
#side_effect_free
def package_list_custom(context, data_dict=None):
datasets = []
dataset_q = (model.Session.query(model.Package)
.join(model.PackageRole))
for dataset in dataset_q:
if dataset.state != 'draft' and dataset.state != 'deleted':
datasets.append(dataset)
return [dataset.id for dataset in datasets]
class Cnaf_WorkflowPlugin(plugins.SingletonPlugin):
plugins.implements(plugins.IActions)
def get_actions(self):
return {
'package_list' : package_list_custom
}
If I modify CKAN core it works very well, but the problem is that I am not to touch it, so I am obliged to do it via an extension.
EDIT: Ok, I managed to make it work, you need to decorate the method with #side_effect_free. I modified my code, and now it works.
The package_search API is capable of this, by searching for state:draft and setting the include_drafts=True flag. Something like this:
https://my-site.com/api/action/package_search?q=state:draft&include_drafts=True
You should be able to access this from a plugin with something like: ckan.plugins.toolkit.get_action('package_search')(context=context, data_dict={'q': 'state:draft', 'include_drafts': True}) (you'll need to assemble the context yourself, containing a 'user' key for the current username and a 'userobj' key for the current user object).
Then make a page from the results.
I have a table that when I click on a row, in a side div I display the details. I have created an event on the row (tr) that is fired every time that row is clicked. The problem I have is that the event is being fired multiple times. It is acting as if a new view is being created everytime the event is fired, but a new view is not being created. Here is the code:
GroupView = class App.GroupView extends Backbone.View
template: App.Utils.getTemplate 'group'
selectedId: 0
events:
'click tr': 'selectGroup'
selectGroup: (e) ->
thisEl = $(e.currentTarget)
$(thisEl).closest('tr').siblings().removeClass 'selected'
$(thisEl).closest('tr').addClass 'selected'
#selectedId = $(thisEl).data().id
#getGroupDetails #selectedId
render: ->
$(#$el).html #template
groups: #collection.models
if #selectedId is 0
firstRowEl = $(#$el).find('tr:first')
$(firstRowEl).addClass 'selected'
#selectedId = $(firstRowEl).data().id
#getGroupDetails #selectedId
getGroupDetails: (id, platform) ->
$('<img/>',
src: 'img/ajax_loader_2.gif'
class: 'ajax-loader'
).appendTo '.group-details'
renderGroupDetails id
groupDetails = new GroupDetailsView
el: '.group-details'
model: groupDetailsModel
renderGroupDetails = (id)->
groupDetails.el = '.group-details'
groupDetails.stopListening groupDetailsModel
groupDetails.listenTo groupDetailsModel, 'change', ->
groupDetails.model =
groupDetails: groupDetailsModel.toJSON()
groupDetails.render()
groupDetailsModel.fetch
data:
id: id
processData: true
The issue is that when I use the groupDetails.stopListening groupDetailsModel, the multiple event firing issue is resolved but then NONE of the events in the groupDetails view is being fired.
Any help is appreciated.
Cheers,
Kianosh
So, giving you a specific answer is difficult: the code you've pasted is a bit hard to follow, and seems like it might be missing bits (eg. what's a groupDetailsModel? Does it have any logic that affects it's view?). That's ok though, because I think what you need here is more debugging help than a specific answer.
If I understand you correctly, your problem is that groupDetails.render() is being invoked extra times, and you're not sure why or what is invoking it: is that correct? If so, your trusty debugger can answer this in a matter of seconds.
NOTE: Everything I'm about to say applies to Chrome (with the built-in developer tools up) or Firefox (with the Firebug extension up) for sure. It probably applies to other browsers with their tools too, I just can't say for sure since I don't use them.
Approach #1: Debugger
With your debugger up, add a debugger; line as the first thing inside your GroupDetails.prototype.render method. This will make your browser pause on that line whenever it hits it. While its paused you can check the "call stack" on the right-hand side, and that will show you exactly what bit of your code just called that render. You can also use the debugger to inspect the values of the different variables in your environment to try and understand why your code is calling render.
Approach #2: Console.trace
If you're not a fan of using the debugger, there's another tool that's also perfect for answering this sort of question. Simply add console.trace() as the first line in your render method, then run your code as normal. This time your browser will log (to the "console") a stack trace generated from that point in the code. This stack trace is similar to the call stack that you can see when you use debugger, and thus it will tell you exactly what code invoked the render each time.
Hope that helps.
I have a requirement to perform an indexed search across content which must include a couple of tags in the result. The tags must be a random selection. The platform is Drupal 7.12
I have created a view that manages the results of a SOLR search through the search_api. The view returns the required content and seems to work as intended. I have included a couple of Global: custom text fields as placeholders for the tag entries.
I am now looking for a solution to manage the requirement to randomise the tag values. The randomisation is not the issue, the issue is how to include the random values into the view result.
My current approach is to write a views_pre_render hook to intercept the placeholders which appear as fields ([nothing] and [nothing_1]). The test code looks like the following
function MODULE_views_pre_render( &$view )
{
$view_display = $view->display['default'];
$display_option = $view_display->display_options;
$fields = $display_option['fields'];
foreach( $view->result as $result )
{
$fields['nothing']['alter']['text'] = sprintf("test %d", rand(1,9));
}
}
I am currently not seeing any change in the placeholder when the view is rendered.
Any pointers to approach, alternate solutions etc would be gratefully received as this is consuming a lot of scarce time at the moment. Calling print_r( $view ) from within the hook dumps over 46M into a log file for a result set of 2 items.
There are two possible solutions for your task.
First approach is do everything on the template level. Define a template for the view field you want to randomize. In advanced settings of your display go to Theme: Information. Make sure that the proper theme is selected and find the template suggestions for your field. They are listed starting from most general to the most specific and you can choose whatever suits you better.
I guess the most specific template suggestion for your field would be something like this: views-view-field--[YOR VIEW NAME]--[YOUR DISPLAY NAME]--nothing.tpl.php. Create the file with that name in the theme templates directory and in this template you can render what ever you want.
By default this template has only one line:
print $output;
you can change this to:
print sprintf("test %d", rand(1,9));
or to anything else, whatsoever :)
Second approach is to go with Views PHP module. WIth this module you can add a custom PHP field in which you can do whatever you want. Even though the module hasn't been released it seems to work quite well for the most of the tasks and most certainly for such a simple task as randomizing numbers it will work out for sure.
I stumbled upon this while searching for another issue and thought I would contribute.
Instead of adding another module or modifying a template, just add a views "sort criteria" of "Global: Random".