What is the best way to denote arrays in ember-data models?

When dealing with an array in a model, is it essential to use DS.hasMany pointing to a DS.Model, even if the array elements are not actual models with IDs or endpoints? Is there a more efficient alternative?

Despite using DS.hasMany with { embedded: true }, I am encountering a 404 error on my extended DS.RESTAdapter without ever calling find. The following error message, which seems to be linked to this particular model, appears for the first time:

Uncaught Error: assertion failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications. ember-latest.js:43

What does this error mean and what might be causing it?

Here's the stack trace:

[Stack Trace Here]

Any assistance would be appreciated.

Update: Referencing this example from the Ember Data documentation: This fiddle, it works with modeled objects as shown in the docs. However, how can similar objects be represented if they are not real models (i.e., do not have IDs)?

Answer №1

Working through the challenge, I managed to make it work by incorporating various answers from this post.

To start off, you need to establish a transform for the new data type "array":

DS.ArrayTransform = DS.Transform.extend({
  deserialize: function(serialized) {
    return (Ember.typeOf(serialized) == "array")
        ? serialized 
        : [];
  },

  serialize: function(deserialized) {
    var type = Ember.typeOf(deserialized);
    if (type == 'array') {
        return deserialized
    } else if (type == 'string') {
        return deserialized.split(',').map(function(item) {
            return jQuery.trim(item);
        });
    } else {
        return [];
    }
  }
});

App.register("transform:array", DS.ArrayTransform);

Next, simply use it in your model as another attribute:

App.myModel = Ember.Model.extend({
    name : DS.attr('string'),
    cont : DS.attr('array')
}

With that, we're all set. Just remember, when adding elements to the array, utilize pushObject.

In a controller:

this.get('model.cont').pushObject('new Item');

Answer №2

My approach involves using a custom raw transform, specifically designed for ember-data revision 11:

DS.RESTAdapter.registerTransform('raw', {
    deserialize: function(serialized) {
        return serialized;
    },  
    serialize: function(deserialized) {
        return deserialized;
    }   
});

After defining the transform, I incorporate it within a model like this:

App.MyModel = Ember.Model.extend({
    anArray: DS.attr('raw')
});

This allows me to utilize the anArray attribute as a standard array throughout my application.

Answer №3

Illustrated below is a demonstration of constructing a personalized array type in Ember-Data (version 10):

DS.CustomArray.array =

  # If the outgoing json is already a valid javascript array
  # then pass it through as is. In all other cases, substitute it
  # with an empty array. This results in null or undefined values
  # automatically transforming into empty arrays during serialization.

  serialize: (jsonData)->
    if Em.typeOf(jsonData) is 'array' then jsonData else []


  # If the incoming data is a javascript array, pass it along.
  # If it is a string, convert it into an array by splitting
  # it based on commas and removing whitespace from each element.
  # Otherwise, return an empty array, turning all other data types
  # (including nulls and undefined values) into empty arrays.

  deserialize: (externalData)->
    switch Em.typeOf(externalData)
      when 'array'  then return externalData
      when 'string' then return externalData.split(',').map((item)-> jQuery.trim(item))
      else               return []

You can now apply the custom type to a model attribute:

App.WeeklySchedule = DS.Model.extend
  selected_days = DS.attr('array')

Upon fetching a record with:

App.WeeklySchedule.find(1)

both forms of incoming JSON records will be deserialized correctly into an Array:

{ selected_days: ['Monday', 'Tuesday', 'Saturday'] }

or

{ selected_days: 'Monday, Tuesday, Saturday' }

Answer №4

With the release of Ember Data 1.0.0 Beta, developers now have the opportunity to create a personalized transform "subclass". This can be thought of as an expanded DS.Transform entity.

DS.ArrayTransform = DS.Transform.extend({
    deserialize: function(deserialized) {
        // ...
        return deserialized;
    },

    serialize: function(serialized) {
        // ...
        return serialized;
    }
});

App.register('transform:array', DS.ArrayTransform);

Answer №5

In the event that you require a specialized data structure to communicate with your server, consider enhancing DS.attr.transforms and defining a new array codec.

Take a look at the source code of existing attribute codecs for guidance on how to implement your own. It serves as an excellent starting point for customization.

Answer №6

Interestingly, all the other four responses to this inquiry share strikingly similar deserialize and serialize functions. This allows for a simplified approach:

import Ember from 'ember'
import DS from 'ember-data'

# It seems that these solutions were inspired by: http://stackoverflow.com/questions/12168570/how-to-represent-arrays-within-ember-data-models
# The key is to ensure that either deserialize or serialize always returns an array

toArray = (data) ->
  switch Ember.typeOf(data)
    when 'array'  then data
    when 'string' then JSON.parse(data)
    else []

export default DS.Transform.extend
  deserialize: toArray
  serialize: toArray

This code snippet utilizes ember-cli-coffees6 for Coffeescript with import/export functionality.

Answer №7

Arriving a bit tardy to the party, but I stumbled upon this jFiddle showcasing a straightforward way to declare a new array codec.

Check it out here!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to reset a state without needing to declare an initialState beforehand?

I'm facing a situation where I need to reset a state without having to create an initial state again. Here's the dilemma: initialState: { id: '', name: '', index: '' }, state: { ...

Error encountered: attempting to build for the iOS Simulator, although linking a dylib compilation specifically for iOS, such as the file 'TitaniumKit.framework/TitaniumKit' for the arm64 architecture

Whenever I attempt to build my appcelerator app for ios, I encounter this error: ld: building for iOS Simulator, but linking in dylib built for iOS, file 'Frameworks/TitaniumKit.framework/TitaniumKit' for architecture arm64 Despite my efforts to ...

Attempting to simulate the behavior of nfcManager by utilizing the nfcManager.start() function in react native testing library

In the process of developing my Android app, I encountered a need to read NFC tags. To accomplish this task, I decided to utilize the react-native-nfc-manager library. However, during my implementation, I faced two perplexing issues that have left me stump ...

Importance of value attribute in <input ng-model ..>

Maybe a silly inquiry, but I'm curious about the purpose of having value="" in this particular situation: <input ng-model="something.name" value="" class="input-xlarge" /> Are there any alternatives to keeping the value attribute empty? I init ...

What steps can be taken to ensure that any new elements generated by JavaScript do not disappear upon refreshing the page

I am currently working on a project where I am creating a list by collecting user information and storing it in a MySQL database. When the user clicks the 'add' button, a new element is added to the bottom of the existing list which is coded in H ...

Angular Js powered admin control panel

Explore the SB Admin Angular by Start Angular My current project involves setting up an admin dashboard on a Windows system. However, I have encountered some issues during the installation process using npm install An error message can be found here ...

Utilize JavaScript to Replace KeyPress Event on Input Field

While attempting to substitute the key press of "K" with "Z" in an input field, I managed to accomplish it successfully. However, there seems to be a slight delay that causes the user to observe the transition from "K" to "Z". Below is the code that I use ...

Error message: 'Encountered issue with react-router-V4 and the new context API in React

Currently, I am experimenting with the integration of React Router V4 alongside the new React context API. Below is the code snippet I am working with: class App extends Component { static propTypes = { router: PropTypes.func.isRequired, ...

Is there a way to transpile a dependency within the node_modules directory when using Nuxt 2?

I have come across challenges when transpiling node_modules with Nuxt, but the latest version of Nuxt (2.0) seems to have addressed this issue by introducing a transpile option in the nuxt.config.js file. https://nuxtjs.org/api/configuration-build/#transp ...

Next.js page transitions causing Google Tag Manager to malfunction with 'react-gtm-module'

I am currently working on a Next.js project and have successfully integrated Google Tag Manager (GTM) using the react-gtm-module package. Interestingly, everything works perfectly when the application is initially loaded in debug mode, regardless of the st ...

Arranging serialized information from a tabular format and retrieving specific data

: I'm currently attempting to utilize an AJAX POST request to send data from a dynamic webpage that includes information gathered from a table form, a date selection box, and comment text input. The webpage is generated as a PHP file on a GET request ...

Utilizing Ajax to Invoke Wordpress Functions from a Client's Browser

Currently working on setting up a WordPress website integrated with WooCommerce, while also developing an HTML5 app for my small online store. I am looking to utilize Ajax to call WordPress functions like search directly from my HTML5 app and receive the r ...

displaying data once "other" is chosen from a dynamic chart

I am having an issue with a dynamic table where I have a dropdown list with the option "other", and I want to display additional input when "other" is selected. Currently, the function I have only hides the input that is always visible and does not show ...

Challenges faced when dealing with MongoDB and the latest version of webpack

Struggling to navigate MongoDB and React.js, encountering issues with MongoDB dependencies. Here are the dependencies listed in package.json: "dependencies": { "dotenv": "^16.3.1", "mongodb": "^4.1.0", &qu ...

The Ubiquity CmdUtils.setSelection function does not support replacing HTML code

I'm working on a Ubiquity command to replace selected links or URLs pointing to images with the actual image itself. However, I've found that the CmdUtils.setSelection() function doesn't work when there are html tags in the selection, render ...

Having trouble locating an element on a webpage? When inspecting the element, are you noticing that the HTML code differs from the source page?

I'm having trouble locating a specific element on a webpage. When I use the Inspect Element tool, I can see the HTML code with the element id = username, but when I check the page source, all I see is JavaScript code. Does anyone have any suggestions ...

Transmitting a JSON string to my backend system to insert into my database, but unfortunately, no data is being added

I've been facing a challenging issue with my code Currently, I am attempting to insert an object into my database using jQuery/AJAX. Despite not encountering any errors, the data is not getting added to my DB. Here is the snippet of my JS/JQuery cod ...

Using $npm_package_ notation to retrieve information about the version of a private package

When using Npm, you can easily access package information from the package.json file by using a helpful prefix. For example, you can extract the react version with $npm_package_dependencies_react to find the current version of react listed in the file. Ho ...

Is Next.js Dynamic Routing Failing You?

Recently, I attempted to implement Dynamic routing for a recipe app but encountered an issue where the page was not found. This problem has left me puzzled as I am fairly inexperienced with TypeScript, although not with React. // pages/recipes/[recipeId].t ...

transforming a div to behave similarly to an iframe

I am trying to load content from my page into a div element using the following function: function loadmypage(DIV, pageURL) { var xmlhttp; if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } e ...