Conditions | 14 |
Total Lines | 77 |
Code Lines | 45 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like tags.js ➔ tagsCard often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | /* |
||
34 | function tagsCard (model, objectId, displayFilter, permRemove) { |
||
35 | // load the tags table |
||
36 | const tagsTable = $('#tags').DataTable({ |
||
37 | ajax: function (data, callback, settings) { |
||
38 | dataTableJsonRPC('Tag.filter', displayFilter, callback, function (data, callback) { |
||
39 | // b/c tags are now annotated with case, run, plan IDs there are duplicate names. |
||
40 | // Filter them out by only looking at Tag.id uniqueness! |
||
41 | data = arrayToDict(data) |
||
42 | callback({ data: Object.values(data) }) |
||
43 | }) |
||
44 | }, |
||
45 | columns: [ |
||
46 | { data: 'name' }, |
||
47 | { |
||
48 | data: null, |
||
49 | sortable: false, |
||
50 | render: function (data, type, full, meta) { |
||
51 | if (permRemove) { |
||
52 | return '<a href="#tags" class="remove-tag" data-name="' + data.name + '"><span class="pficon-error-circle-o hidden-print"></span></a>' |
||
53 | } |
||
54 | return '' |
||
55 | } |
||
56 | } |
||
57 | ], |
||
58 | dom: 't', |
||
59 | language: { |
||
60 | loadingRecords: '<div class="spinner spinner-lg"></div>', |
||
61 | processing: '<div class="spinner spinner-lg"></div>', |
||
62 | zeroRecords: 'No records found' |
||
63 | }, |
||
64 | order: [[0, 'asc']] |
||
65 | }) |
||
66 | |||
67 | // remove tags button |
||
68 | tagsTable.on('draw', function () { |
||
69 | $('.remove-tag').click(function () { |
||
70 | const tr = $(this).parents('tr') |
||
71 | |||
72 | jsonRPC(model + '.remove_tag', [objectId, $(this).data('name')], function (data) { |
||
73 | tagsTable.row($(tr)).remove().draw() |
||
74 | }) |
||
75 | }) |
||
76 | }) |
||
77 | |||
78 | // add tag button and Enter key |
||
79 | $('#add-tag').click(function () { |
||
80 | addTag(model, objectId, $('#id_tags')[0], tagsTable) |
||
81 | }) |
||
82 | |||
83 | $('#id_tags').keyup(function (event) { |
||
84 | if (event.keyCode === 13) { |
||
85 | addTag(model, objectId, $('#id_tags')[0], tagsTable) |
||
86 | }; |
||
87 | }) |
||
88 | |||
89 | // tag autocomplete |
||
90 | $('#id_tags.typeahead').typeahead({ |
||
91 | minLength: 3, |
||
92 | highlight: true |
||
93 | }, { |
||
94 | name: 'tags-autocomplete', |
||
95 | // will display up to X results even if more were returned |
||
96 | limit: 100, |
||
97 | async: true, |
||
98 | display: function (element) { |
||
99 | return element.name |
||
100 | }, |
||
101 | source: function (query, processSync, processAsync) { |
||
102 | jsonRPC('Tag.filter', { name__icontains: query }, function (data) { |
||
103 | // b/c tags are now annotated with case, run, plan IDs there are duplicate names. |
||
104 | // Filter them out by only looking at Tag.id uniqueness! |
||
105 | data = arrayToDict(data) |
||
106 | return processAsync(Object.values(data)) |
||
107 | }) |
||
108 | } |
||
109 | }) |
||
110 | } |
||
111 |
This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.