Why Angular ngFor does not check if the iterable object existing? - angularjs

I am complete new to Angular 2. My understanding of Angular 2 is that it is based on TypeScript which compiles the source code to Javascript. As a compile language, I would expect it is able to catch any undefined variable, but it seems that it is not the case for ngFor. For example, in the following code (I am using VS Code), ngFor is used for iterate object heroes, it does not give me any error if heroes is not defined (when I defined heroes, I got a typo and defined it as heros, last second line):
import { Component } from '#angular/core';
*export class Hero {
id: number;
name: string;
}
const HEROES: Hero[] = [
{ id: 11, name: 'Mr. Nice' },
{ id: 12, name: 'Narco' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas' },
{ id: 15, name: 'Magneta' },
{ id: 16, name: 'RubberMan' },
{ id: 17, name: 'Dynama' },
{ id: 18, name: 'Dr IQ' },
{ id: 19, name: 'Magma' },
{ id: 20, name: 'Tornado' }
];
#Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes" >
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
`
})
export class AppComponent {
name = 'Angular';
title = 'Tour of Heroes';
heros = HEROES;
}*
Could somebody kindly explain to me why? Do I expect too much?

If the property referenced by *ngFor to iterate over is null or undefined, *ngFor just doesn't do anything. You won't get an error for this.
TypeScript is a superset of JavaScript and undefined is a perfectly valid value for a property in JS and TS.
Angular2 for Dart however produces an error for such cases.

Related

line 14 Expected an assignment or function call and instead saw an expression error

I'm am trying to map over seeded data, and I'm getting this error. Does anyone know why? Right now I am only trying to get the key of name to display, but I'm getting an expected an assignment or functionn error.
import { Link } from "react-router-dom";
import {getData} from "../Data"
export default function Home() {
let data = getData();
return (
<div>
{data.map((data) => {
{data.name}
})}
</div>
)
}
This is my seed data that I am trying to pull from.
I have imported it in my home.jsx file and called the function before my return statement.
let data = [
{
name: 'forgive-me-pleases',
image: 'https://i.imgur.com/0UCzcZM.jpg',
price: 50,
tags: ['pink', 'roses', 'bouquet', 'apologies'],
},
{
name: 'pink perfection',
image: 'https://i.imgur.com/XoEClf7.png',
price: 15,
tags: ['pink', 'gerbera daisy', 'singular', 'decor'],
},
{
name: 'hopeful sunshine',
image: 'https://i.imgur.com/LRrcBtN.png',
price: 30,
tags: ['yellow', 'sunflower', 'multiple', 'garden'],
},
{
name: 'motivational mug',
image: 'https://i.imgur.com/NOJ2ikN.png',
price: 25,
tags: ['yellow', 'gerbera daisy', 'singular (with mug)'],
},
{
name: 'breathtaking bouquet',
image: 'https://i.imgur.com/TuuKiHt.png',
price: 40,
tags: ['white', "baby's breath", 'bouquet', 'decor'],
},
{
name: 'loves-me-loves-me-knots',
image: 'https://i.imgur.com/SaTbTEx.png',
price: 20,
tags: ['mixed', 'gerbera daisy', 'mini bouguet', 'for fun'],
},
{
name: 'hiya, spring',
image: 'https://i.imgur.com/dJvHolr.jpg',
price: 35,
tags: ['mixed', 'hyacinths', 'bouquet', 'garden'],
},
{
name: 'can of compassion',
image: 'https://i.imgur.com/PN3jmrf.png',
price: 55,
tags: ['mixed', 'decor', 'bouquet (with can)', 'love'],
},
{
name: 'basket of beauty',
image: 'https://i.imgur.com/Z86X3qq.png',
price: 50,
tags: ['mixed', 'bouquet (with basket)', 'love', 'decor'],
},
];
export function getData() {
return data
}
Please change your code like below
let data = getData();
return (
<div>
{data.map((data) => {
<div>{data.name}</div>
})}
</div>
)

How to render a React component with survey.js?

Here is a working survey.js with react example: http://plnkr.co/edit/qXdeQa6x2FHRg0YrOlPL?p=preview
My html also does have in head the <script src="https://unpkg.com/survey-react"></script> included.
In my main.jsx I'm calling the rendering of a div that will be filled up based on a json file and by multiple react components, in my json array I have a questions json object too for survey.js. What I would like to achieve is to render a survey when the questions object is being reached in parsing the array.
In my top level component I have this calling for it:
if (section.hasOwnProperty('questions')){
return <Questions key={i+"questions"} id={i+"questions"} questions={section.questions} />;
The Questions.jsx:
var React = require('react');
var ReactDOM = require('react-dom');
var Survey = require('survey-react');
var Questions = React.createClass({
render: function() {
Survey.Survey.cssType = "bootstrap";
Survey.defaultBootstrapCss.navigationButton = "btn btn-green";
window[this.props.id] = new Survey.Model( this.props.questions );
var questionid = this.props.id;
var idi = this.props.id.replace("questions","");
return (
<dt>
<div id={this.props.id}></div>
</div>
</dt>
);
}
});
module.exports = Questions;
ReactDOM.render(<Survey.Survey model={window[questionid]} />, document.getElementById({questionid}));
It does compile without errors but then in the browser I get the console errors:
TypeError: WEBPACK_IMPORTED_MODULE_1_react is undefined[Learn
More]
ReferenceError: questionid is not defined
Seems like I try to do it the wrong way, but how to do it right? I'm new to react and not familiar with using reactDOM inside of a component and is my first project on survey.js as well.
Thank you for helping out.
Please check this code:
import React, { Component } from 'react';
import { render } from 'react-dom';
import * as Survey from 'survey-react';
import 'survey-react/survey.css';
import 'bootstrap/dist/css/bootstrap.css'
import './style.css';
class App extends Component {
componentWillMount() {
Survey.Survey.cssType = "bootstrap";
Survey.defaultBootstrapCss.navigationButton = "btn btn-green";
}
render() {
var json = { title: "Product Feedback Survey Example", showProgressBar: "top", pages: [
{questions: [
{ type: "matrix", name: "Quality", title: "Please indicate if you agree or disagree with the following statements",
columns: [{ value: 1, text: "Strongly Disagree" },
{ value: 2, text: "Disagree" },
{ value: 3, text: "Neutral" },
{ value: 4, text: "Agree" },
{ value: 5, text: "Strongly Agree" }],
rows: [{ value: "affordable", text: "Product is affordable" },
{ value: "does what it claims", text: "Product does what it claims" },
{ value: "better then others", text: "Product is better than other products on the market" },
{ value: "easy to use", text: "Product is easy to use" }]},
{ type: "rating", name: "satisfaction", title: "How satisfied are you with the Product?",
mininumRateDescription: "Not Satisfied", maximumRateDescription: "Completely satisfied" },
{ type: "rating", name: "recommend friends", visibleIf: "{satisfaction} > 3",
title: "How likely are you to recommend the Product to a friend or co-worker?",
mininumRateDescription: "Will not recommend", maximumRateDescription: "I will recommend" },
{ type: "comment", name: "suggestions", title:"What would make you more satisfied with the Product?", }
]},
{questions: [
{ type: "radiogroup", name: "price to competitors",
title: "Compared to our competitors, do you feel the Product is",
choices: ["Less expensive", "Priced about the same", "More expensive", "Not sure"]},
{ type: "radiogroup", name: "price", title: "Do you feel our current price is merited by our product?",
choices: ["correct|Yes, the price is about right",
"low|No, the price is too low for your product",
"high|No, the price is too high for your product"]},
{ type: "multipletext", name: "pricelimit", title: "What is the... ",
items: [{ name: "mostamount", title: "Most amount you would every pay for a product like ours" },
{ name: "leastamount", title: "The least amount you would feel comfortable paying" }]}
]},
{ questions: [
{ type: "text", name: "email",
title: "Thank you for taking our survey. Your survey is almost complete, please enter your email address in the box below if you wish to participate in our drawing, then press the 'Submit' button."}
]}
]};
var model = new Survey.Model(json);
return (
<Survey.Survey model={model}/>
);
}
}
render(<App />, document.getElementById('root'));
and here a live example: https://stackblitz.com/edit/surveyjs-react-stackoverflow45544026

How can I populate a SELECT in a data grid?

I have this object:
phraseFormId = [
{
id: 1,
name: 'Word'
}, {
id: 2,
name: 'Sentence'
}
];
What I would like to do is to change this read only row.formId to be a SELECT element where it will display and where I can choose new values:
<div>
<div>{{ row.formId}}</div>
</div>
Can anyone give me some ideas how I can do this?
Thanks
Certainly not sure, what exactly you are looking for but have a look on this fiddle, simple enough to start with. Let me know, if your problem statement is different.
Using
ng-repeat
Fiddle: http://jsfiddle.net/U3pVM/26336/
It is a little unclear exactly what you are asking for, but I think I may have found a solution.
Here is a DEMO
Let me know if this is what you were looking for!
It utilizes ng-options with select to create a dropdown with values that will bind to a model property
Html
<div ng-repeat="item in phraseFormId">
<h4 ng-bind="'Item ' + $index"></h4>
id: {{item.id}}<br>
name: {{item.name}}<br>
formId:
<select ng-model="item.formId" ng-options="id for id in formIds"></select>
</div>
Controller
$scope.formIds = [1,2,3];
$scope.phraseFormId = [
{
id: 1,
formId: 1,
name: 'Word'
}, {
id: 2,
formId: 2,
name: 'Sentence'
},
{
id: 3,
formId: 1,
name: 'Paragraph'
}, {
id: 4,
formId: 3,
name: 'Sentence'
}
];

kendo ui angularjs grid edit

I'm doing a POC for AngularJS and Kendo UI and I need to know how to save updated data on a kendo grid. I have inline editing enabled but can't hook into kendo UI to get the updated data. I created a fiddle (http://jsfiddle.net/aMz7V/14/) but can't get the jsfiddle to work (sorry this is my first time creating a fiddle), so I have pasted the code below:
JavaScript (controller code):
var myApp = angular.module('myApp', ['kendo.directives']);
myApp.controller("gridCtrl", function($scope) {
$scope.assignments = {};
$scope.assignments.dataSource = new kendo.data.DataSource({
data: [
{ StudentName: "John Smith", HomeWork: 9, HomeWork1: 12 },
{ StudentName: "Kodjo Adu", HomeWork: 5, HomeWork1: 15 },
{ StudentName: "Patrick smith", HomeWork: 10, HomeWork1: 19 },
{ StudentName: "Richard lomax", HomeWork: 8, HomeWork1: 18 },
{ StudentName: "Aglade Bone", HomeWork: 7, HomeWork1: 20 }
],
schema: {
model: {
fields: {
StudentName: { type: "string" },
HomeWork: { type: "number" },
HomeWork1: { type: "number" },
}
}
},
pageSize: 3,
});
$scope.assignments.columns = [
{ field: 'StudentName', title: 'Student Name' },
{ field: 'HomeWork', title: 'Home Work / 10' },
{ field: 'HomeWork1', title: 'Home Work / 20' }
];
});
HTML:
<div ng:app="myApp">
<div ng-controller='gridCtrl'>
<div kendo-grid k-data-source="assignments.dataSource" k-selectable="'row'"
k-pageable='{ "refresh": true, "pageSizes": true }'
k-columns='{{assignments.columns}}' k-sortable="true" k-editable="true" k-toolbar="['save','cancel']"></div>
</div>
</div>
So i figured it out, to handle to the save changes event i needed to do this
k-on-save-changes="saveChanges(kendoEvent)"
and just add the saveChanges function to the $scope in the controller.

Highcharts- Unable to change yAxis label

I am trying to render charts using the Highcharts js-library. As I am working with AngularJS, I am using an AngularJS directive for HighCharts.
I made everything work fine but due to some weird reason, I am unable to change the yAxis label value.
I get the default value "Values" shown on the chart's y-axis, which I checked is defined in the highcharts.js file under "defaultYAxisOptions".
Html:
<div ng-app="myapp">
<div ng-controller="myctrl">
<highchart id="chart1" config="chart"></highchart>
</div>
</div>
Javascript:
var myapp = angular.module('myapp', ["highcharts-ng"]);
myapp.controller('myctrl', function ($scope) {
$scope.chart = {
options: {
chart: {
type: 'bar'
}
},
xAxis: {
title: {
text: 'x-axix-label'
}
},
yAxis: {
title: {
text: 'y-axix-label'
}
},
series: [{
data: [10, 15, 12, 8, 7]
}],
title: {
text: 'Hello'
},
loading: false
}
});
Sample implementation: http://jsfiddle.net/VwTCn/9/
Can someone please point out the mistake here.
Took me a while, to understand, that highcharts-ng doesn't work, using the original highcharts options structure.
Anyway, for some reason it works, if you put you yAxis config into the options object, like this:
...
options: {
chart: {
type: 'bar'
},
yAxis: {
title: {
text: 'y-axis label'
}
}
},
xAxis: {
title: {
text: 'x-axis label'
}
},
series: [{
...
See example: http://jsfiddle.net/martinczerwi/VwTCn/13/

Resources