The question is how to format firebase to work with angular. I have a view that works with ng as a static view. In the $scope it is defined like this
$scope.standardItems = [{
name: "The Name",
sizeX: 2,
sizeY: 1,
row: 0,
col: 0
}, {......etc
But if I try and supply data from firebase it does not work probably because the output is not formatted correctly. The connection seems fine and I can add data but firebase adds it own id. This is the how the data looks exported from the firebase console
{
"-KdJVcYUXMfeym3jPy04" : {
"att" : "grid",
"col" : 0,
"id" : 1487476528646,
"name" : "This is a test grid",
"row" : 0,
"sizeX" : 2,
"sizeY" : 1
},
The extra parameters are not important but the nesting probably is. I have logged the out put of the firebase array using this
var todosRef = new Firebase('https://xxxxxxxxxx.firebaseio.com/');
$scope.todos = $firebaseArray(todosRef);
console.log($scope.todos);
And I get this in the chrome debug console
Array[0]
0:Object
$id: "-KjhbuvgtVvFUnbfbmj04"
$priority:null
att:"grid"
col:0
id:1487476528646
name:"This is a test grid"
row:0
sizeX:2
sizeY:1
__proto__
Here is the important line from the view using angular ng-repeat
<li gridster-item row="item.position[0]" col="item.position[1]" size-x="item.size.x" size-y="item.size.y" ng-repeat="item in todos">
//..
</li>
My question is how do I pass to angular (the view) exactly what is being passed in the static example above from the controller? How can I "print" exactly what is being passed to angular from the array - the export from firebase console and chrome log console are not totally the same. It does not help that all the parent nodes are unique non sequential IDs such as -KdJVcYUXMfeym3jPy04 as it is not obvious how to strip them off again - or how to use a word such as "grid". Do I need a wildcard in the path and if so what is it? The code works using a static local array so it is all about reading json from firebase.
OK, I hope this answer is helpful. There is nothing wrong with the code posted here! Angular js will read firebase without any changes and the outputs from the chrome console and the firebase console should look like they are here even with the "-adgadhfe445ggh45" added id index. In my case I made a syntax error that excluded the ng-repeat from the the controller because it fell outside and its closing div
But at least we now know that we do not need any code to reformat the firebase.
Related
I'm new to Sequelize and try to achieve the following:
Assume I have a very simple database with 3 Models/Tables:
Person, Group and Category.
Person has a Many-To-One relation to Group (1 Person can be in 1 Group, 1 Group holds multiple people) & Group has a Many-To-One relation to Category (1 Group has 1 Category, 1 Category can be applied to multiple Groups).
Because I don't want to save the whole Category in my database, but only a short string, I have a mapper in the backend in my app.
Let's say my Category-Mapper looks like this:
//category.mapper.js
module.exports = Object.freeze({
cat1: "Here is the String that should be sent to and displayed by the FrontEnd",
cat2: ".....",
});
So basically, in my database I save "cat1" as the category and every time I get one or more Categories via Sequelize from the database, I want to go into my mapper, resolve the short string to the long string and send it to the Frontend, so I wrote the following code:
//category.model.js
const categoryMapper = require("../mapper/category.mapper");
Category.afterFind((models) => {
if(!Array.isArray(models)) {
models = [models];
}
models.forEach(model => {
model.name = categoryMapper[model.name];
});
});
This works great when I call Category.findAll()..., but does not trigger when I include the Category as in this example:
Group.findAll({
include: [Category]
})
There is this rather old GitHub Issue referencing this behavior, where someone published some code to make sure the hooks run on include. See here.
I tried implementing the referenced code into my project, but when I do, the hook for Category runs twice in my following code:
Person.findAll({
include: [{
model: Group,
include: [Category]
}]
})
My assumption is, that, with the code from the GitHub-Issue comment, my hook gets triggered every time the relationship is detected and the code runs. Therefore the hook runs once after including Group, because Group has a relationship to Category and a second time when Category is actually included, which breaks my mapping function because the second time it tries to resolve the long string, which doesn't work.
I'm looking for a solution that basically runs my hooks once and only once, namely when the actual include for my model triggers, regardless of on what level the include happens.
Sorry for the lengthy post, but I did not find any solution to my problem online, but don't believe what I am trying to achieve is very exotic or specific to my project only.
If there is a better solution I am not seeing, I'm open to suggestions and new approaches.
Thanx in advance!
I am relatively new to Meteor, and I'm trying to create a web store for my sister-in-law that takes data from her existing Etsy store and puts a custom skin on it. I've defined all of my Meteor.methods to retrieve the data, and I've proofed the data with a series of console.log statements... So, the data is there, but it won't render on the screen. Here is an example of some of the code on the server side:
Meteor.methods({
...
'getShopSections': function() {
this.unblock();
var URL = baseURL + "/sections?api_key="+apiKey;
var response = Meteor.http.get(URL).data.results;
return response;
}
...
});
This method returns an array of Object. A sample bit of JSON string from one of the returned Objects from the array:
{
active_listing_count: 20,
rank: 2,
shop_section_id: 1******0,
title: "Example Title",
user_id: 2******7
}
After fetching this data without a hitch, I was ready to make the call from the client side, and I tried and failed in several different ways before a Google search landed me at this tutorial here: https://dzone.com/articles/integrating-external-apis-your
On the client side, I have a nav.js file with the following bit of code, adapted from the above tutorial:
Template.nav.rendered = function() {
Meteor.call('getShopSections', function(err, res) {
Session.set('sections', res);
return res;
});
};
Template.nav.helpers({
category: function() {
var sections = Session.get('sections');
return sections;
}
});
And a sample call from inside my nav.html template...
<ul>
{{#each category}}
<li>{{category.title}}</li>
{{/each}}
</ul>
So, there's a few things going on here that I'm unsure of. First and foremost, the DOM is not rendering any of the category.title String despite showing the appropriate number of li placeholders. Secondly, before I followed the above tutorial, I didn't define a Session variable. Considering that the list of shop categories should remain static once the template is loaded, I didn't think it was necessary from what I understand about Session variables... but for some reason this was the difference between the template displaying a single empty <li> tag versus a number of empty <li>'s equal to category.length --- so, even though I can't comprehend why the Session variable is needed in this instance, it did bring me one perceived step closer to my goal... I have tried a number of console.log statements on the client side, and I am 100% sure the data is defined and available, but when I check the source code in my Developer Tools window, the DOM just shows a number of empty li brackets.
Can any Meteor gurus explain why 1) the DOM is not rendering any of the titles, and 2) if the Session variable indeed necessary? Please let me know if more information is needed, and I'll be very happy to provide it. Thanks!
You set the data context when you use #each, so simply use:
<li>{{title}}</li>
If a Session is the right type of reactive variable to use here or not is hard to determine without knowing what you are doing but my rough guess is that a Mini Mongo collection may be better suited for what it appears you are doing.
To get you started on deciding the correct type of reactive variable to use for this head over to the full Meteor documentation and investigate: collections, sessions, and reactive vars.
Edit: To step back and clarify a bit, a Template helper is called a reactive computation. Reactive computations inside of helpers will only execute if they are used in their respective templates AND if you use a reactive variable inside of the computation. There are multiple types of reactive variable, each with their own attributes. Your code likely didn't work at all before you used Session because you were not using a reactive variable.
I am trying to use the meteor rubaxa:sortable package to make a list sortable in my meteor app.
The list I am attempting to sort is actually nested in a document in Curriculums. It looks like this...
{'id' : 123,
'cratedAt' : timestamp,
'resources' : object
}
the resources objects look like this
{'id' : 232, 'order' : 1}, {'id': 344, 'order' : 2} ....
I used a helper function to pull the one item from curriculums I want to display.
return CurriculumList.findOne({_id: this.params._id})
Then use {{#sortable items=resources}} in my template. The output is just like the {{#each}}, and the items are draggable and sortable. However when I look at the console, i recieve this error:
rubaxa_sortable.js:1333
Uncaught TypeError: templateInstance.collection.findOne is not a function
How can I make this package properly update my 'order' field?
The problem is that resources is an array. For a solution, refer to the workaround in Issue #287 on GitHub.
Issue #194, which points to Issue #287, contains a MeteorPad example very similar to the example you give.
Also, the person who opened GitHub Issue #539 is getting the same error and equates it to the problem in Issue #194.
Note, as well, that according to Issue #366, you get the same error if the collection is empty.
I have a JSON doc in the following format and need to use that to dynamically build check boxes using angular.
var data = {
"Name":[
{
"tagId":4489,"name":"Name","label":"Employee Name"
}
],
"Service":[
{
"tagId":1722,"name":"good service","label":"Good Service"
},
{
"tagId":3707,"name":"bad service","label":"Bad Service"
}
]};
I am just learning Angular js and the project I am working on will need the check boxes in the following format.
Name
[ ] Employee Name
Service
[ ] Good Service
[ ] Bad Service
The JSON is loaded on startup with ajax in my main controller. I am not quite sure how let Angular build this for me using the ng-repeat function.
Any help is appreciated.
Check out my fiddle. I belive my answer is a bit more complete than Khalil's.
http://jsfiddle.net/nicolasmoise/8YQPh/1
I have created a factory .factory('checkBoxFactory', function(){}) which takes the JSON object and adds a check="false" to every tag. This may not be necessary, but I believe it's better to set the values right away in case the user doesn't touch them.
Finally, I have directive .directive('checkboxes', function(){}) which takes the checkboxes I have created through the factory and creates the desired markup. With this you can change the name of your categories (Name, Service) and it still works.
Let me know if this is not what you had in mind or if you have questions.
I made a jsfiddle of the most basic example of what you're looking for over here.
Basically I just attached data to the scope and iterated over both lists, "Service" and "Name" and used inputs with type=checkbox(angular docs) and attached an ng-model linked to a check value on each object (this will be added by angular when you activate the checkbox).
You can monitor the values of the checkboxes by referencing check on each object. I do this by doing ng-repeat="service in data.Service" and then calling service.check.
I'm trying to develop an application using the Fixture Adapter with Ember-Data.
When I try and create a new object (based on a model I've defined), it won't work unless I specify the ID.
If I specify the ID and do this:
var person = SD.Person.createRecord({
id: 234,
name: "test"
});
var person.save();
I get:
Error: assertion failed: An adapter cannot assign a new id to a record
that already has an id. had id: 234 and you
tried to update it with 234. This likely happened because your server
returned data in response to a find or update that had a different id
than the one you sent.
Which makes it sound like somehow I'm updating an existing record (I'm not, there's only 2 fixtures for my Person object with ID's of 1 and 2 respectively).
Is Ember trying to save my object twice somehow?
I thought I may have to try and use generateIdForRecord to set the ID, but I can't reference that function no matter what I try.
newBooking.set('id', this.store.generateIdForRecord(this.store, newBooking));
newBooking.set('id', DS.generateIdForRecord(this.store, newBooking));
newBooking.set('id', this.generateIdForRecord(this.store, newBooking));
newBooking.set('id', generateIdForRecord(this.store, newBooking));
TypeError: this.store.generateIdForRecord is not a function
I'm using the latest releases of Ember and Ember-Data (have tried previous releases too). My model is implemented no differently to the TodoMVC tutorial in the Ember guides and in the tutorial nothing fancy needs to be done to manage ID's with the Fixture adapter so I've really no idea what's going on.
How do I create a new Person object (as per my example, just one 'name' field and persist it using Ember-Data's fixture adapter without the aforementioned errors?
In the end, my first code snippet worked fine.
For some reason, I was expecting to see the new object being persisted in the developer console. My models were being listed in a different view so I didn't realize it was actually working as intended.