I am trying to load the value from the local sqlite dB (which I have tested and the values are there) into a global model that I can use in my views. When I try to print the values of the model after creating it using Ti.API.info(library.at(i));in index.js, it returns undefined most of the time and sometimes a function call like function lastIndexOf() { [native code] }. What is going on and how can I fix it? Here is my model (UpcomingRaces.js):
exports.definition = {
config: {
columns: {
"Name": "string",
"Location": "string",
"Date": "string",
"Url": "string"//,
//"Id" : "INTEGER PRIMARY KEY AUTOINCREMENT"
},
defaults: {
"Name": "string",
"Location": "string",
"Date": "string",
"Url": "string"
},
adapter: {
type: "sql",
collection_name: "UpcomingRaces",
//idAttribute: "Id"
}
},
extendModel: function(Model) {
_.extend(Model.prototype, {
// extended functions and properties go here
});
return Model;
},
extendCollection: function(Collection) {
_.extend(Collection.prototype, {
// extended functions and properties go here
comparator: function(UpcomingRaces) {
return UpcomingRaces.get('Name');
}
});
return Collection;
}
};
Here is how I am reading it into a model (index.js):
var library = Alloy.Collections.UpcomingRaces;
library.fetch();
function prepareView()
{
// Automatically Update local DB from remote DB
updateRaces.open('GET', 'http://fakeurl.com/api/UpcomingRaces');
updateRaces.send();
library && library.fetch();
// Read DB to create current upcomingRaces model
// Insert the JSON data to the table view
for ( var i in library ) {
Ti.API.info(library.at(i));
data.push(Alloy.createController('row', {
Name : library[i]['Name'],
Date : library[i]['Date']
}).getView());
}
$.table.setData(data);
}
Also I've got this in my alloy.js file
Alloy.Collections.UpcomingRaces = Alloy.createCollection('UpcomingRaces');
the problem is with your for loop:
// Insert the JSON data to the table view
for ( var i in library ) { // i here is an instance of the Model, not an index
Ti.API.info(library.at(i)); // <-- error here
data.push(Alloy.createController('row', {
Name : library[i]['Name'],
Date : library[i]['Date']
}).getView());
}
no need to call library.at(i), just use i element. So the correct code would be:
// Insert the JSON data to the table view
for ( var element in library ) {
Ti.API.info(JSON.stringify(element));
data.push(Alloy.createController('row', {
Name : element.get('Name'),
Date : element.get('Date')
}).getView());
}
Related
I am trying to convert from an introspection query to a GraphQL schema using the npm GraphQL library.
It keeps stating:
devAssert.mjs:7 Uncaught Error: Invalid or incomplete introspection result. Ensure that you are passing "data" property of introspection response and no "errors" was returned alongside: { ... }
Issue is I am getting it directly from GraphiQL Shopify and can't figure out how to validate my introspection return is correct.
Code:
var introspection = `
{
"data": {
"__schema": {
"types": [
{
"name": "Boolean"
},
{
"name": "String"
},
{
"name": "QueryRoot"
},
{
"name": "Job"
},
{
"name": "ID"
},
{
"name": "Node"
},
{
"name": "Order"
}
]
}
},
"extensions": {
"cost": {
"requestedQueryCost": 2,
"actualQueryCost": 2,
"throttleStatus": {
"maximumAvailable": 1000,
"currentlyAvailable": 980,
"restoreRate": 50
}
}
}
}`;
let schema = buildClientSchema(introspection);
//console.log(schema.printSchema());
I thought the introspection result could be a string? Or is there not enough info to build a schema? Do I need to expand the number of fields? What's the bare minimum needed to exchange an introspection result into a schema?
You should use getIntrospectionQuery to get the complete introspection query needed. If the response you're working with is a string, it should then be parsed to an object before being passed to buildClientSchema -- the function accepts an object, not a string.
Here's an example directly querying a schema using the graphql function -- you'll need to modify it based on how you're actually executing the query.
const { getIntrospectionQuery, buildClientSchema, graphql } = require('graphql')
const schema = new GraphQLSchema(...)
const source = getIntrospectionQuery()
const { data } = await graphql({ source, schema })
const clientSchema = buildClientSchema(data)
Make sure that you are only passing in the data portion of the response. The object you pass in should look like this:
{
__schema: {
// ...more properties
}
}
I am trying to create mock data by using the json-server in combination with the json-schema-faker.
I was trying to use the $ref property but I understood that this only references the type and not the exact value.
Is there a way to reuse the exact same value instead of just its type?
The schema I have in mockDataSchema.js file is:
var schema =
{
"title": "tests",
"type": "object",
"required": [
"test"
],
"properties": {
"test": {
"type": "object",
"required": [
"id",
"test2_ids",
"test3"
],
"properties": {
"id": {
"type": "string",
"faker": "random.uuid" // here
},
"test2_ids": {
"type": "array",
"items": {
"type": "string",
"faker": "random.uuid" // here
}
},
"test3": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"faker": "random.uuid" // here
}
}
}
}
}
}
}
};
module.exports = schema;
From this schema I want the id to be the same in all three locations which i have indicated with the comment // here.
Note that I can't use an enum or const as I want to have multiple tests occurrences.
test2_ids will be an array so i would like to include that specific id for the first id and other values of the same type as well..
In the id of test3 i just want the exact same value as the id of test.
Is it feasible what I am trying to achieve?
Or is there a way to change these data in the generateMockData.js file instead of the mockDataSchema.js which includes this schema ?
My generateMockData.js :
var jsf = require('json-schema-faker');
var mockDataSchema = require('./mockDataSchema');
var fs = require('fs');
var json = JSON.stringify(jsf(mockDataSchema));
fs.writeFile("./src/api/db.json", json, function (err) {
if (err) {
return console.log(err);
} else {
console.log("Mock data generated.");
}
});
I'd like to share here a solution that I found. In my case, I required to generate the same value for the fields password and password_confirmation using json-schema-faker, and something that worked for me was, assign a new property in the faker library and put the new property name inside the faker schema. Here the code:
import faker from 'faker';
import jsf from 'json-schema-faker';
// here we generate a random password using faker
const password = faker.internet.password();
// we assign the password generated to a non-existent property, basically here you create your own property inside faker to save the constant value that you want to use.
faker.internet.samePassword = () => password;
// now we specify that we want to use faker in jsf
jsf.extend('faker', () => faker);
// we create the schema specifying the property that we have created above
const fakerSchema = {
type: 'object',
properties: {
password: {
faker: 'internet.samePassword',
type: 'string'
},
password_confirmation: {
faker: 'internet.samePassword',
type: 'string'
}
}
};
// We use the schema defined and voilá!
let dataToSave = await jsf.resolve(fakerSchema);
/*
This is the data generated
{
password: 'zajkBxZcV0CwrFs',
password_confirmation: 'zajkBxZcV0CwrFs'
}
*/
I have a javascript object with nested objects obtained by a plugin saved in a variable called 'json':
// var json:
Object {0: Object, 1: Object}
0: country
countryCapital: Object
ministers: Array[1]
1: country
countryCapital: Object
ministers: Array[3]
// Should be restructured to fit MVC models
World
Country Array [2]
Capital: Object
Minister: Array [1]
Because I'm sending the data using jQuery-ajax to a MVC controller I'm trying to rename/restructure them to bind them to a MVC Model so I can send the whole 'World' object as 1 parameter.
// Controller
[HttpPost]
public void Save(World world)
// Model structure:
World
* Country (list)
1 Capital
* Minister (list)
How do I convert the javascript object to the right structure that fits the Model parameter? Do I need to loop everything or can it be done in a better way?
UPDATE:
json object update, it's a lot of data so I simplified it.
// World
{
"0": { // Country
"ministers":
{
"objects": [
{
"name": "name1"
},
{
"name": "name2"
}
]
},
"countryCapital": {
"name": "...",
}
},
"1": { // Country
"ministers":
{
"objects": [
{
"name": "name1"
},
{
"name": "name2"
}
]
},
"countryCapital": {
"name": "...",
}
}
}
I suppose you're searching for $.map().
At the background it's looping your collection but it much cleaner to use it in your case.
Updated to use your example json. Jsfiddle
var world = {}
for (var countryIteration in originalObject) {
var country = originalObject[countryIteration];
world[countryIteration] = { //you need to this because you need dynamic keys.
capital : country.countryCapital.name,
ministers : country.ministers.objects
}
}
I found a working solution thanks to teo van kot using jQuery map.
var world = {}
$.map(json, function (value, i) {
if (i == "countryCapital") {
world.Capital = value
}
if (i == "ministers") {
world.Minister= value
$.each(value, function (j, minister) {
world.Minister[j].Name = minister.name;
delete minister.name;
});
}
}, world);
I'm trying to deal with a server response, and am a little confused how to turn the json response into Backbone Models.
My Backbone model looks like so:
Entities.Recipe = Backbone.Model.extend({
defaults: {
id: '',
name: '',
introduction: ''
},
parse: function (response)
{
if(._isObject(response.results)){
return response.results
else {
return response
}
})
Entities.RecipeCollection = Backbone.Collection.extend({
url: 'recipes',
model: Entities.Recipe
)}
var API = {
getRecipeEntities: function (){
var recipes = new Entities.RecipeCollection()
var defer = $.Deferred()
recipes.fetch({
url: 'http://3rdpartyApilocation.com/recipes'
success: function (data) {
defer.resolve(data)
}
})
var promise = defer.promise()
$.when(promise).done(function (fetchedData)
{})
return promise
}
RecipeManager.reqres.setHandler('recipe:entities', function()
{
return API.getRecipeEntities()
}
And the response.results is an Array of objects - with each object having an id key, a name key and an introduction key. But because I am so inexperienced with Backbone I have no idea how to map those results to the model?
I have installed Chromes Marionette inspector and when I look at the entire array of results seems to be passed to the model, rather than each individual object within each response.result being set to each individual model. Sorry if I can't be more clear - I'm very new to Backbone...
Perhaps your confusion is because you're in fact able to use parse on a model or on a collection. And from your explanation it looks like the response.results object returns a list of objects that you want to become models in your application. But because you're catching that object in a model, the model doesn't know what to do with that array.
Let's say you have a response like this:
{
"status": "ok",
"results": [
{
"id": 1,
"name": "Pie"
}, {
"id": 2,
"name": "Rice"
}, {
"id": 3,
"name": "Meatballs"
}
]
}
Then you would just use parse on your Collection to let it know the response isn't array itself, and help it find it in the results property.
Here's a working example:
var Recipe = Backbone.Model.extend();
var Recipes = Backbone.Collection.extend({
model: Recipe,
url: 'http://www.mocky.io/v2/56390090120000fa08a61a57',
parse: function(response){
return response.results;
}
});
var recipes = new Recipes();
recipes.fetch().done(function(){
recipes.each(function(recipe){
/** Just demo of the fetched data */
$(document.body).append('<p>'+ recipe.get('name') +'</p>');
});
});
<script src='http://code.jquery.com/jquery.js'></script>
<script src='http://underscorejs.org/underscore.js'></script>
<script src='http://backbonejs.org/backbone.js'></script>
I'm new to backbone and I'm trying to set a collection of models with data loaded from a json-file. But it won't get set. Whats the problem here? Anyone having an idea? When i fetch the collections it seems that its empty.
JSON
{
"items": [
{
"id": "0",
"media": "",
"desc": "lorem",
"img": "ipsum"
},
{
"id": "1",
"media": "",
"desc": "lorem",
"img": "ipsum"
}
]
}
Javscript
var Card = Backbone.Model.extend({
defaults: function() {
return {
items: {
id: "lorem",
media: "lorem",
desc:"lorem",
img: "lorem"
}
};
},
clear: function() {
this.destroy();
}
});
var CardCollection = Backbone.Collection.extend({
model: Card,
url: "file.json",
parse: function (response) {
for (var i = 0; i<response.items.length; i++) {
}
}
});
var cards = new CardCollection();
cards.fetch();
console.log(cards)
fetch is asynchronous, it returns immediately before the data has been loaded.
Try this
var cards = new CardCollection();
cards.fetch({
success: function () {
console.log(cards);
}
});
The CardCollection.parse method is called with the response. If no transformation is required to the response from the server, you can remove the parse method of the CardCollection. The default implementation is pass thru and the response is used as-is.
Basically parse should return the array to be added to the collection. The current implementation does not do anything. return is missing for the implementation.
Just return something from your parse method and you are good to go. It is expected to return an array of objects and each object will fit into your model. So finally you will have a collection of models corresponding to array of objects being returned from parse method.
Try this
var CardCollection = Backbone.Collection.extend({
model: Card,
url: "file.json",
parse: function (response) {
return response.items;
}
});
Read this Documentation on Parse Method for more information.