{"id":1933,"date":"2022-08-30T15:20:39","date_gmt":"2022-08-30T15:20:39","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/12\/05\/passing-in-an-observablearray-as-a-function-parameter-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:20:39","modified_gmt":"2022-08-30T15:20:39","slug":"passing-in-an-observablearray-as-a-function-parameter-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/passing-in-an-observablearray-as-a-function-parameter-collection-of-common-programming-errors\/","title":{"rendered":"Passing in an observableArray as a function parameter-Collection of common programming errors"},"content":{"rendered":"<p>What I&#8217;m trying to achieve: A form with one text input field(Name), two select fields with some options(Type &amp; Column) with a submit button that creates a Widget with it&#8217;s title set to Name, data-type set to Type and Column &#8211; being it&#8217;s position in the page.<\/p>\n<p>Type in this case has a couple of different options defined in the view, it works just dandy so I won&#8217;t go into how I got that working, for now.<\/p>\n<p>As of now I have a page with three columns, each as it&#8217;s own observableArray &#8211; like so:<\/p>\n<pre><code>self.col0 = ko.observableArray([]);\nself.col0.id = 'col0'\n<\/code><\/pre>\n<p>The same goes for col1 and col2. My goal here is to get the select field to point to these arrays. Atleast that&#8217;s what I think I need to do.<\/p>\n<p>I have a createWidget function, that looks at the Name and Type values in the DOM (Correct me if I&#8217;m wrong here, this is the very first thing I&#8217;m creating with KnockOut) and creates a new Widget from that data &#8211; like so:<\/p>\n<pre><code>var Widget = function(name, type) {\n  var self  = this;\n  self.name = name;\n  self.type = type;\n}; \n\nvar ViewModel = function() {\n  var self = this;\n  self.newWidgetName = ko.observable();\n  self.newType       = ko.observable();\n\n\/\/ Unrelated code in between\n\nself.createWidget = function(target) {\n  newName = self.newWidgetName();\n  newType = self.newType();\n  widget  = new Widget(newName, newType);\n  target.unshift(widget)\n  self.newWidgetName(\"\");\n};\n<\/code><\/pre>\n<p>The input\/select elements in the DOM<\/p>\n<pre><code>input.widget-name type=\"text\" placeholder=\"wName\" data-bind=\"value: newWidgetName\"\n\nselect data-bind=\"value: newType\"\n  option value=\"calendar\" Calendar\n  option value=\"article\"  Article\n  option value=\"document\" Document\n\nselect.colPick data-bind=\"value: colPick\"\n  option value=\"col0\" Column 1\n  option value=\"col1\" Column 2\n  option value=\"col2\" Column 3\n<\/code><\/pre>\n<p>And my click handler for the createWidget function &#8211; like so:<\/p>\n<pre><code>a.btn.create-widget data-bind=\"click: function(){ createWidget(col0); }\"\n<\/code><\/pre>\n<p><strong>Shazam, it works!<\/strong><\/p>\n<p>However, this will only ever output the new Widget into the first col (col0), it won&#8217;t take the value of the column select field into account and unshift the new widget into the correct column. The errors I&#8217;m getting after much trial and error pretty much boils down to:<\/p>\n<p>1) &#8220;Cannot call method unshift of undefined&#8221;<\/p>\n<p>2) &#8220;Uncaught TypeError: Object function observable() &#8230;. has no method &#8216;unshift&#8217;<\/p>\n<p>So as of right now the code looks like the example above, It&#8217;s not ideal by any means but with the different columns connected with knockout-sortable, it&#8217;s not a huge deal if this functionality has to get scrapped. The user can still move the Widgets around from col0 to col2 and vice versa.<\/p>\n<p>If anyone has a resource that would point me in the right direction, or the answer up their sleeve &#8211; feel free to share!<\/p>\n<p>All the best, Kas.<\/p>\n<p><strong>Edit: Followup questions for Tyrsius<\/strong><\/p>\n<p>With the code you supplied I now have the three columns working in the select box, however I am struggling a bit when it comes to outputting the Widgets into view.<\/p>\n<p>With my previous code, this is what the view looked like:<\/p>\n<pre><code>\n  \n    <\/code><\/pre>\n<ul data-bind=\"sortable: { template: 'widgetTmpl', data: col0, afterMove: $root.widgetData }\"><\/ul>\n<pre>\n  \n  \n    <\/pre>\n<ul data-bind=\"sortable: { template: 'widgetTmpl', data: col1, afterMove: $root.widgetData }\"><\/ul>\n<pre>\n  \n  \n    <\/pre>\n<ul data-bind=\"sortable: { template: 'widgetTmpl', data: col2, afterMove: $root.widgetData }\"><\/ul>\n<pre>\n  \n\n<\/pre>\n<p><code>What I'm working with right now is this:<\/code><\/p>\n<pre><code><code>\n  \n    <\/code><\/code><\/pre>\n<ul data-bind=\"sortable: { template: 'widgetTmpl', data: columns, afterMove: $root.widgetData }\"><\/ul>\n<pre>\n  \n\n<\/pre>\n<p><code>My first question, I realised I wasn't thinking at the time so skip that one.<\/code><\/p>\n<p><code>Question #2: How would I now get these Widgets bound to the col that I picked in the form? Would I do this?<\/code><\/p>\n<ul data-bind=\"sortable: { template: 'widgetTmpl', data: entryColumn, afterMove: $root.widgetData }\"><\/ul>\n<pre>\n<\/pre>\n<p><code>Or am I way off? :)<\/code><\/p>\n<ol>\n<li>\n<p><code>I would keep a collection of the items on the column as a type, which would look like this:<\/code><\/p>\n<pre><code><code>var Column = function(header) {\n    this.header = ko.observable(header);\n    this.items = ko.observableArray([]);\n};\n<\/code><\/code><\/pre>\n<p>The trick would be to bind the column <code>select<\/code> straight to the list of columns on your viewmodel:<\/p>\n<\/li>\n<\/ol>\n<p id=\"rop\"><small>Originally posted 2013-12-05 09:40:16. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>What I&#8217;m trying to achieve: A form with one text input field(Name), two select fields with some options(Type &amp; Column) with a submit button that creates a Widget with it&#8217;s title set to Name, data-type set to Type and Column &#8211; being it&#8217;s position in the page. Type in this case has a couple of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1933","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1933","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=1933"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/1933\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=1933"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=1933"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=1933"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}