TypeError: Illegal invocation at forEach when creating attachments

455 views Asked by At

trying to create an attachment to the associating model, but have an error, do not know how to debug it

firefox says 'forEach' called on an object that does not implement interface FormData;

chrome - TypeError: Illegal invocation at forEach at copy ==

(forEach(destination, function(value, key)

return copy(source, emptyObject, stackSource, stackDest); )

for creating attachments angularjs-rails-resource is used https://github.com/FineLinePrototyping/angularjs-rails-resource

form

.modal-header
  %h3(ng-hide="attachment.id")!= @t('.title_new', attachmentable: "{{'activerecord.models.'+attachment.primaryRelation+'.one'|t}}")
  %h3(ng-show="attachment.id")!= @t('.title_edit')

%form(name="attachmentForm" ng-model-options='{updateOn: "keydown blur select change", debounce: {keydown: 500}}' novalidate ng-controller="AttachmentFormController")
  .modal-body.form-horizontal
    .form-group
      %label.col-sm-3.control-label!= @t('activerecord.attributes.attachment.name')
      .col-sm-9
        %input.form-control(type="text" ng-model="attachment.name" model-errors="attachment.$errors.name" required focus-on="true")

    .form-group
      %label.col-sm-3.control-label!= @t('activerecord.attributes.attachment.file')
      .col-sm-9(ng-show="attachment.file")
        %div(model-errors="attachment.$errors.file")
          %i(file-input-state="attachment.file")
          %span.attachment!= JST.render('attachments/_attachment', model: 'attachment')

          .btn-group.btn-group-sm
            %button.btn.btn-default.remove(ng-click="removeFile()")
              %i.fa.fa-ban
              = @t('actions.remove')

      .col-sm-9(ng-hide="attachment.file")
        %file-input(name="attachment.file" title="#{@t('.upload_file')}" ng-model="attachment.file" file-selected="fileSelected($file)" bootstrap-file-input model-errors="attachment.$errors.file")

  .modal-footer
    %button.btn.btn-primary(ng-hide="attachment.id" ng-show="$can('create', attachment)" ng-click="modal.create()" ng-disabled="attachmentForm.$invalid || modal.$busy")
      %i.fa.fa-spin.fa-spinner(ng-show="modal.$busy")
      != @t('actions.create')
    %button.btn.btn-primary(ng-show="attachment.id && $can('update', attachment)" ng-click="modal.update()" ng-disabled="attachmentForm.$invalid")!= @t('actions.save')
    %button.btn.btn-default(ng-click="modal.cancel()")= @t('actions.close_modal')

ModalController

angular.module('modals').controller 'ModalController', [
  '$scope', '$uibModalInstance', '$injector', 'resource', 'actionName',
  ($scope, $uibModalInstance, $injector, resource, actionName) ->
    ctrl = this

    resourceName = resource.constructor.config.name
    $scope[_.lowCamelize(resourceName)] = resourceCopy = angular.copy(resource)

    ...

    @create = ->
      ctrl.$busy = true
      # here is failure on create
      resourceCopy.create().then((createdResource) ->
        $uibModalInstance.close(createdResource)
      ).finally ->
        ctrl.$busy = false
   
    ....

factory

angular.module('railsResource').factory 'RailsResourceNotificatorMixin', [
  '$rootScope', ($rootScope) ->

    resourceName = (constructor) ->
      _.lowCamelize(constructor.config.name)

    class RailsResourceNotificatorMixin
      @extended: (Resource) ->
        
        ...

        Resource::create = ->
          debugger

          # super is Resource.__super__.create.apply(this, arguments).then(function(resource) {
          # here is failure
          super.then (resource) ->
            $rootScope.$broadcast("#{resourceName(Resource)}-created", resource)
            resource
resourceCopy =
Object { fileName: "sample.pdf", fileSize: 8573, company: {…}, primaryRelation: "company", companyId: 121, name: "sdfsf", file: {"$upload": Object { "$$state": {…}, success: success(fn), state: "done-ok", … } id: "3243365014180998090"} }
1

There are 1 answers

0
ABA On

It turned out that in angularjs-rails-resource gem angular.copy did not want to copy an object with attachments

https://github.com/FineLinePrototyping/dist-angularjs-rails-resource/blob/v2.0.0/angularjs-rails-resource.js#L1461

{
  "id": 201,
  "ticketId": 133,
  "creatorId": 63,
  "importedFromMyCustomer": false,
  "myCustomerCompanyid": null,
  "myCustomerCaseId": null,
  "myCustomerNoteSeqNbr": null,
  "content": "Veniam asperiores officia numquam...",
  "deletedAt": null,
  "createdAt": "2020-10-20T16:54:18.000+03:00",
  "updatedAt": "2020-10-23T10:24:59.000+03:00",
  "updaterId": 1,
  "isModified": true,
  "attachments": [
    {
      "fileName": "sample.pdf",
      "fileSize": 8573,
      "file": {
        "$upload": {
          "$$state": {
            "status": 1,
            "value": {
              "data": {
                "id": "2810473018465773169"
              },
              "status": 201,
              "config": {
                "method": "POST",
                "transformResponse": [
                  null
                ],
                "url": "/uploads",
                "file": {},
                "headers": {
                  "Accept": "application/json, text/plain, */*",
                  "X-Requested-With": "XMLHttpRequest",
                  "X-XSRF-TOKEN": "3fCWvLQU5rcMpc/kQJvKLsrTJeVtdV8bk2w2/lmynHEekEdBY+GqfPNUkanxBz1tE+AP4qgTGBEbr8UaAx/FOA=="
                },
                "data": {}
              },
              "statusText": "Created"
            },
            "processScheduled": false
          },
          "state": "done-ok",
          "result": {
            "$$state": {
              "status": 1,
              "value": {
                "id": "2810473018465773169"
              },
              "processScheduled": false
            }
          },
          "uploadedFile": {
            "id": "2810473018465773169"
          }
        },
        "id": "2810473018465773169"
      }
    },
    {}
  ],
  "creator": {
    "id": 63,
    "firstName": "Coralie",
    "lastName": "Brekke",
    "username": "user_pedro_62",
    "email": "[email protected]",
    "lastSignInAt": null,
    "currentSignInAt": null,
    "teamId": 22,
    "name": "Coralie Brekke",
    "avatarUrl": "/avatars/small/missing.png",
    "teamName": "Prosacco Group 22",
    "enabled": true,
    "phone": null
  },
  "$editing": true
}

temporary fix is to override

data = angular.copy(this, {})

to

data = JSON.parse(JSON.stringify(this))